0

I have tasks which are sending various messages with data.

For example:

task.Comm.Send(MSG_JOB_ERROR,[string, string,string,string,string, TObject]) ;

On the receiving side I have

procedure TUDPBroadCast.OnWorkerJobError(var msg: TOmniMessage);
var 
    s : String ;
begin
    try
        s := 'TASK: ' + msg.MsgData.AsArrayItem[0].AsString + ', IP: ' +    
             msg.MsgData.AsArrayItem[1].AsString + ', PORT: ' + 
             msg.MsgData.AsArrayItem[2].AsString +
             ', DATA: ' + msg.MsgData.AsArrayItem[3].AsString + ', REPLY: '+  
             msg.MsgData.AsArrayItem[4].AsString  ;
        Xlog('JOB ERROR > ' + s, 'UDPBroadCast') ;
        processworkobject(msg.MsgData.AsArrayItem[4].AsObject) ; 
    finally
        msg.MsgData.Clear ;
    end;
end; 

But I don't feel that MsgData.Clear will correctly unallocate all memory.

What is the correct handling of TomniValue deallocation?

2 Answers2

1

You have to take care of freeing the object that TOmniMessage holds. At least as far as I know. Simple types are no problem, also intefaces gets clear on their own because of reference counting. But as for pure pointers and TObject descendants you have to call free on them. You have to take care of the memory they use.

TOmniMessage only contains the reference pointer to the actual memory used by them.

So you should do something like that:

msg.MsgData.AsObject.Free;
msg.MsgData.Clear;

or in case of pure pointers

FreeMem(msg.MsgData.AsPointer)
msg.MsgData.Clear;

I also forgot to add. Only do that if you are responsible for the memory they point to :)

Runner
  • 6,073
  • 26
  • 38
0

msg.MsgData is a TOmniValue. In the most recent versions of OmniThreadLibrary, TOmniValue can own its object by setting TOmniValue.OwnsObject:=True, and has some other helper methods to facilitate this functionality. If OwnsObject is true, then the object is freed when the TOmniValue is freed, so you do not have to worry about memory management as much any longer.

Dave Novo
  • 693
  • 3
  • 9