sunstone
|
|
« on: October 22, 2010, 04:33:45 AM » |
|
Dear,
Pls see the unit of rtcinfo.pas
------------------------------- procedure TRtcInfo.Set_Object(const index: String; pObj: TObject); var uindex: String; ob: TObject; begin if not assigned(ObjList) then ObjList := tStringObjList.Create(32);
uindex := UpperCaseStr(index); ob := ObjList.search(uindex); if ob <> nil then begin if pObj = nil then ObjList.remove(uindex) else begin // Kill the old object ONLY if it was directly replaced with another one if ob is TRtcObject then TRtcObject(ob).Kill; ObjList.change(uindex, pObj); end; end else if pObj <> nil then ObjList.Insert(uindex, pObj); end;
------------------------------- => if ob is TRtcObject then => TRtcObject(ob).Kill;
if the object of 'ob' has been freed. but it is not nil,then to kill the ob,the system will create exception.
I don't know it is right ?
Best regards, sunstone
|
|
|
Logged
|
|
|
|
D.Tkalcec (RTC)
|
|
« Reply #1 on: October 22, 2010, 09:49:16 AM » |
|
The code in the "rtcInfo.pas" unit is correct (no bug).
If you are receiving an exception there, it means that you have destroyed the object (manually) before removing its reference from the parent, which is something you should NOT do. If you want to destroy child objects, you have to remove/extract them from parent objects first. Any objects left assigned to parent objects will be destroyed with the parent once the parent is destroyed, or when the property to which the child was assigned is re-assigned.
Best Regards, Danijel Tkalcec
|
|
|
Logged
|
|
|
|
sunstone
|
|
« Reply #2 on: October 23, 2010, 02:27:40 AM » |
|
pls see your demo of RTC_Messenger.When you run the server and client,and then login a user,after 10s, there will raise a exception in server.
The reason is the cb has been destroyed,but the procedure of TRtcInfo.Set_Object still to kill it.
So it is better to put the 'kill' out of the Set_Object. I think that the object should be destroyed by the programer.
|
|
|
Logged
|
|
|
|
D.Tkalcec (RTC)
|
|
« Reply #3 on: October 23, 2010, 07:11:06 AM » |
|
I don't see any exceptions raised on either the Server nor the Client side when I test the RTC Messenger Demo and leave the client logged in for 10 seconds. Are you sure you haven't made changes to the RTC Messenger Client or Server code which cause this exception?
As said ... the implementation in the "rtcInfo.pas" unit is correct.
If a TRtcObject is being replaced by another TRtcObject in a parent TRtcObject, the "kill" method has to be called on the old TRtcObject instance. If there is an exception raised, it is because of a bug in the code using the RTC SDK and not because the call to "Kill" should be removed from the method you have posted.
You should NEVER destroy objects linked to other objects. Before you destroy an object, you have to remove all its references to other objects. If you get an exception in the "TRtcInfo.Set_Object" method, it means that you have destroyed an object assigned to TRtcInfo BEFORE you have removed its reference from the TRtcInfo instance.
Best Regards, Danijel Tkalcec
|
|
|
Logged
|
|
|
|
sunstone
|
|
« Reply #4 on: October 25, 2010, 03:59:28 AM » |
|
I tested in Win7 and Win xp. It is ok in Win7.
This exception only been raised in Win XP the exception is :
Msg_client
Access violation at address 004053F4 in module 'MSG_Server.exe'.Read of address FFFFFFD0
|
|
|
Logged
|
|
|
|
D.Tkalcec (RTC)
|
|
« Reply #5 on: October 25, 2010, 07:54:15 AM » |
|
As said ... I can't reproduce the problem you are having. Can you please debug the code to find out what exactly is causing this exception? The least I need is a complete call-stack to know what is calling the method which raises the exception. If you are using a modified version of the Messenger Demo project, please check if the same exception happens in the original version.
Best Regards, Danijel Tkalcec
|
|
|
Logged
|
|
|
|
sunstone
|
|
« Reply #6 on: October 25, 2010, 09:18:29 AM » |
|
pls run the server and client in Windows XP. This exception will be raised.
by the way , your client demo could not delete the friend. When you login next time,the friend which has been deleted still exists.
|
|
|
Logged
|
|
|
|
D.Tkalcec (RTC)
|
|
« Reply #7 on: October 25, 2010, 08:14:53 PM » |
|
Found and fixed the bug. It was in the "TMessenger_Provider.MsgGetDataExecuteMethod" in the "rtcMessengerProvider.pas" unit ("RTC_MessengerServer" Project).
The exception raised in the "rtcInfo.pas" unit was correct and was helpful in pin-pointing the source of the actual problem. The problem was that a callback object (TRtcDelayedCall) was NOT removed from the "user" list when it should have been, which resulted in the object being destroyed twice.
Here is a fixed method implementation ...
procedure TMessenger_Provider.MsgGetDataExecute (Sender: TRtcConnection; Param: TRtcFunctionInfo; Result: TRtcValue); var thischeck:TDateTime; arr:TRtcArray; cb:TRtcDelayedCall; begin cb:=nil;
CheckLogin(Sender, Param['user']);
if not Param.asBoolean['delayed'] then begin { Set "delayed" parameter to TRUE, before preparing the call, because only changes we do to Param before we send it to the PrepareDelayedCall function will be memorized, while any changes we do to Param afterwards will be discarded. } Param.asBoolean['delayed']:=true; { Prepare delayed call, which will be triggered in 10 seconds in case the callback function is not used until then. } cb:=PrepareDelayedCall(10000, Param, MsgGetDataExecute); user.SetCallback(Param['user'],cb); end;
arr:=user.GetData(Param['user'],Param['check'],thischeck); if assigned(arr) then begin // don't need delayed call, new data is ready to be sent now! user.SetCallback(Param['user'],nil); CancelDelayedCall(cb);
with Result.NewRecord do begin asObject['data']:=arr; asDateTime['check']:=thischeck; end; end else if assigned(cb) then PostDelayedCall(cb) else // -> LINE ADDED!!! user.SetCallback(Param['user'],nil); // <- LINE ADDED!!! end;
Best Regards, Danijel Tkalcec
|
|
|
Logged
|
|
|
|
sunstone
|
|
« Reply #8 on: October 26, 2010, 02:08:07 AM » |
|
Thanks for your correction. Now it runs OK.
|
|
|
Logged
|
|
|
|
|