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

Reply via email to