• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 592
  • Last Modified:

Socket Problem in Mutli-threaded Application *URGENT*

Hi guys,

I have a problem working with CSocket in a mutli-threaded application. Basically, I created my sockets in the main application, then passed the SOCKET handles to the my worker thread via my dialog class object (since CSocket objects asserts when they're passed directly to another thread).

After using the sockets in my worker thread, I want to be able to transfer the control of the sockets back to my main user interface (UI) thread. My problem lies in that after the worker thread ends and transfers the sockets back to my original UI thread, they're unable to work. ie: my sockets don't work on an OnReceive() notification anymore.


//------------- code begins --------
// defined elsewhere
HANDLE m_hSocket, m_hTCPSocket;
CSocket m_pSocket, m_pTCPSocket;


CClientDialogDlg::StartThread()
{
:
:
// my sockets are detached at this point
m_hSocket = m_pSocket->Detach();
m_hTCPSocket = m_pTCPSocket->Detach();
AfxBeginThread(WorkerThread, this);
}

UINT WorkerThread( LPVOID pParam )
{
// The follow code is a workaround the VC++ 6.0 bug (see article Q193101)
#ifndef _AFXDLL
#define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE
#define _afxSockThreadState AfxGetModuleThreadState()

_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
if (pState->m_pmapSocketHandle == NULL)
pState->m_pmapSocketHandle = new CMapPtrToPtr;
if (pState->m_pmapDeadSockets == NULL)
      pState->m_pmapDeadSockets = new CMapPtrToPtr;
if (pState->m_plistSocketNotifications == NULL)
      pState->m_plistSocketNotifications = new CPtrList;
#endif
// end workaround

CClientDialogDlg* dlg = (CClientDialogDlg*) pParam;
CSocket Socket;
CSocket TCPSocket;
Socket.Attach(dlg->m_hSocket);
TCPSocket.Attach(dlg->m_hTCPSocket);
:
// Socket, TCPSocket operations
:
// WM_ATTACH_SOCKET message mapped to CClientDialogDlg::AttachSocket()
dlg->SendMessage(WM_ATTACH_SOCKET);
return 0;
}

void CClientDialogDlg::AttachSocket()
{
m_pSocket->Attach( m_hSocket );
m_pTCPSocket->Attach( m_hMmSocket );

// after this point my sockets cannot work anymore on the UI thread
}
0
zoukker
Asked:
zoukker
1 Solution
 
manloreCommented:
You must Detach again the sockes at the end of the thread.

// Socket, TCPSocket operations
:

// Detach sockets
Socket.Detach();
TCPSocket.Detach();

// WM_ATTACH_SOCKET message mapped to CClientDialogDlg::AttachSocket()
dlg->SendMessage(WM_ATTACH_SOCKET);
return 0;
}

0
 
zoukkerAuthor Commented:
Opps, I'm terribly sorry, especially to you, manlore! I omitted the Detach() parts from my question, but not my original code...

my thread code is as follows.. but it still fails as before...

UINT WorkerThread( LPVOID pParam )
{
// The follow code is a workaround the VC++ 6.0 bug (see article Q193101)
#ifndef _AFXDLL
#define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE
#define _afxSockThreadState AfxGetModuleThreadState()

_AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
if (pState->m_pmapSocketHandle == NULL)
pState->m_pmapSocketHandle = new CMapPtrToPtr;
if (pState->m_pmapDeadSockets == NULL)
pState->m_pmapDeadSockets = new CMapPtrToPtr;
if (pState->m_plistSocketNotifications == NULL)
pState->m_plistSocketNotifications = new CPtrList;
#endif
// end workaround

CClientDialogDlg* dlg = (CClientDialogDlg*) pParam;
CSocket Socket;
CSocket TCPSocket;
Socket.Attach(dlg->m_hSocket);
TCPSocket.Attach(dlg->m_hTCPSocket);
:
// Socket, TCPSocket operations
:

// detach portions
Socket.Detatch()
TCPSocket.Detatch()
// WM_ATTACH_SOCKET message mapped to
CClientDialogDlg::AttachSocket()
dlg->SendMessage(WM_ATTACH_SOCKET);
return 0;
}
0
 
c_hummCommented:
It might be helpful to know what you are doing with your sockets in the workerthread and the UI-thread. Tried to reproduce your problem but the
following scenario works:
UI-thread: Listen for incoming connection, accept it, start workerthread
                 and detach
Worker:    Attach, receive, and detach.
UI-thread:Attach and receive.
0
 
JanvoCommented:
There is a known problem passing MFC dialogs across threads, also as you know it is only safe to pass sockets after they are detached.   Instead of passing your entire dialog, pass a pointer to a structure that contains both detached socket handles, and perhaps the HWND of the dialog.  That way you can reattach the sockets via the structure, and you can also send messages to your dialog.  I am thinking that the temporary memory map for your dialog is getting messed up when it is being tossed between threads, which will of course affect messaging.  This should work, Good Luck!
0
 
ShaunWildeCommented:
you should only use CSockets inside a CWinThread type thread
0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now