I have a TWSocket descendant called TWSocketClientDeluxe. It does its work on a background thread. I have confirmed that this is the case by setting breakpoints on various events and inspecting the Threads window to make sure it is not on the main thread. It creates its own client thread and its Multithreaded property is TRUE.
I recently changed my Send() method override to post buffers to the client thread so that the actual Send() takes place on the worker thread and not on the thread that calls TWSocketClientDeluxe.Send(). To facilitate this, the custom message loop I created to replace the base class method has custom windows messages for executing certain relevant requests and for processing the Send() data requests posted by TWSocketClientDeluxe.Send(). The client thread message loop then takes those buffers and calls a method I created called BgSend(). That method simply calls the base class Send() method (inherited Send()). I am having various problems so I am posting the code I wrote for the client thread's custom message loop to see if any of you see any problems with it. It's a little lengthy so my apologies in advance. The reason I have taken such extreme measures like moving to a background thread and decoupling the Send() operation is to avoid any thread blocking issues as much as I can. My application is the middleman between two sockets that cooperate in a multiple real-time audio streams. Therefore, I have to grab the buffer from one socket and send it out the other as quickly as possible. Hence the extreme measures. Note, the interface object retrieved from the MsgRec was already _AddRef'd an extra time before it was posted to make sure it did not destroy prematurely when recovered by the custom message loop. Here's the code, hopefully the formatting doesn't fall apart in your E-mail reader. Please comment on anything that is wrong or might cause instabilities or problems: ------------------ Custom Message Loop For Socket Client Thread -------- while GetMessage(MsgRec, 0, 0, 0) do begin TranslateMessage(MsgRec); // Is it a request to execute a custom background thread request? if MsgRec.message = WM_BG_CUSTOM_SOCKET_REQUEST then begin // ATI: 1-10-2012: Custom background thread request. // // If our owner socket is a TWSocketClientDeluxe instance and // we have a custom background request event handler, then // call it now. if WSocket is TWSocketClientDeluxe then begin theSockCliDeluxe := TWSocketClientDeluxe(WSocket); if Assigned(theSockCliDeluxe.OnBgCustomRequestProc) then theSockCliDeluxe.OnBgCustomRequestProc(MsgRec); end; // if WSocket is TWSocketClientDeluxe then end // Is it a request to reconnect with the same settings as the // last connect (current settings)? else if MsgRec.message = WM_BG_SOCKET_RECONNECT then begin // If we are not "closed" then this is an error. if not (WSocket.State = wsClosed) then raise Exception.Create('(TClientThread.Execute) A reconnect request was received when our socket was not in the "closed" state. Socket name: ' + WSocket.Name); // --------------- RECONNECT --------------- // Re-connect. WSocket.Connect; end // if (GAUNTLET) then else if MsgRec.message = WM_BG_SOCKET_SEND_REQUEST then begin // -------------- SEND DATA REQUEST ------------------ // Recover the send data request interface. intf := nil; P := Pointer(MsgRec.lParam); if not Assigned(P) then raise Exception.Create('(TClientThread.Execute) Long parameter was not assigned, received pointer invalid while recovering the IPostBufferToCollection interface.'); Move(P, intf, sizeof(intf)); if not Assigned(intf) then raise Exception.Create('(TClientThread.Execute) Received an unassigned interface object.'); if not Supports(intf, IClientSocketSendDataRequest, intfCliSockSendDataReq) then raise Exception.Create('(TClientThread.Execute) Interface object received is not a IClientSocketSendDataRequest interface.'); if not Assigned(intfCliSockSendDataReq.data) then raise Exception.Create('(TClientThread.Execute) The send data request has an unassigned data pointer.'); if intfCliSockSendDataReq.dataLen <= 0 then raise Exception.Create('(TClientThread.Execute) The send data request''s buffer length is less than or equal to 0.'); // Send the data now but use the background send method that // calls the inherited Send() method directly or we // will create a recursive self-posting situation. with WSocket as TWSocketClientDeluxe do BgSend(intfCliSockSendDataReq.data, intfCliSockSendDataReq.dataLen); // Release the interface variables we used. intf := nil; intfCliSockSendDataReq := nil; end else // Pass it on. DispatchMessage(MsgRec); end; // while() -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be