RTC Forums
May 05, 2024, 10:16:30 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: Is it a bug?  (Read 5054 times)
sunstone
RTC License++
*****
Posts: 16


« 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)
Administrator
*****
Posts: 1881


« 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
RTC License++
*****
Posts: 16


« 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)
Administrator
*****
Posts: 1881


« 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
RTC License++
*****
Posts: 16


« 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)
Administrator
*****
Posts: 1881


« 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
RTC License++
*****
Posts: 16


« 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)
Administrator
*****
Posts: 1881


« 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
RTC License++
*****
Posts: 16


« Reply #8 on: October 26, 2010, 02:08:07 AM »

Thanks for your correction. Now it runs OK.
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.026 seconds with 16 queries.