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
}
zoukkerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ShaunWildeCommented:
you should only use CSockets inside a CWinThread type thread
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.