[omniORB] NT Thread Question (updated)
Sai-Lai Lo
S.Lo@orl.co.uk
Tue, 19 May 1998 18:31:57 +0100
Hi! Back on-line again after 2 weeks of absence.
Have you applied my patch on omnithread
(http://www.orl.co.uk/omniORB/bugs/18.html) so that it works with native
threads?
This is **essential** if you are using native threads (or Afxthread).
Without the patch, it is only by chance that your callback seems to work.
Let me try to explain:
1. Without the patch, native threads calling on omni_condition.wait() would
result in a omnithead fatal exception. The patch removes this
restriction.
2. When the callback object is invoked first time, the ORB connects to the
client. Until the connect call succeeds, any concurrent calls on the same
callback object would be blocked on a omni_condition variable. Because
of (1), the thread bombs out with the exception. This (uncaught)
exception causes the process to abort.
3. When the client is NT, I suspect the connect call succeeds so quickly
that it happens before the thread doing the second callback has a chance
to run yet. When the client is win95, the connect call is slower and
hence you see (2) happening.
My suggestion is to apply the patch, and retest.
If you still see the same problem, I'll have to think it over again.
Keep us updated.
Sai-Lai
>>>>> Robert H Fritz writes:
> Hi Everyone,
> This is a follow-up to a question I submitted last week. Thanks to everyone
> who responded. I've gotten partial but unusual results. To recap, I've got
> a Win95 machine running as a client and an NT40 workstation acting as a
> server. The client is calling a oneway method on the server and passing an
> object reference (of itself) to the server. When the server-method
> completes, the server callsback a client-method using this object reference.
> This arrangement worked fine until I re-implemented the server method using
> AfxBeginThread.
> Here's the behavior:
> When client and server are both running local to the NT40 machine, the
> client can run submit multiple simultaneous-commands to the server. All
> server threads begin and end normally. No problems.
> When the win95 machine is acting as client, I can submit as many commands as
> I wish, one at a time -- waiting for one thread to complete before
> submitting another. Each thread will execute and terminate normally. But I
> end up with a single memory leak. When I submit two (or more) commands
> without waiting for the first thread to complete, the first will execute
> fine. But I get a protection exception on the *second* thread with the
> following trace-back:
> KERNEL32! 77f1cd91()
> MSVCRT! 78008d93()
> OMNIORB25_RT! 1000e284()
> _proxy_Echo_Client::echoString(char * 0x0165faf0) line 465
> DoCmdThreadProc(void * 0x00cd1ef0) line 198
> _AfxThreadEntry(void * 0x0155fc88) line 113 + 13 bytes
> _threadstartex(void * 0x00cd2120) line 212 + 13 bytes
> Where ......
> void _proxy_Echo_Client::echoString ( const char * mesg )
> {
> CORBA::ULong _0RL_retries = 0;
> _0RL_again:
> assertObjectExistent();
> omniRopeAndKey _0RL_r; <-----------------$$$$$ THIS IS LINE 465 in the
> EchoSK file ... $$$$$
> CORBA::Boolean _0RL_fwd = getRopeAndKey(_0RL_r);
> CORBA::Boolean _0RL_reuse = 0;
> And this is the result of calling-back the client method.
> So my minor problem is what could be the source of the server memory leak
> when called
> from a "foreign" client. Should I release the CORBA::strdup()? But my
> major problem is what is
> the source of the exception ...
> Any info appreciated.
> Rob Fritz
> rfritz@geologics.com
> The relevant code is relatively simple:
> // An item of this type is passed to the thread.
> //
> typedef struct
> {
> Echo_Client_ptr m_rcEchoClient;
> const char *m_lpszcmd;
> } tCDoCmdThreadInfo;
> // This is the oneway server method invoked by the client
> //
> void
> Echo_Server_i::doCMD ( Echo_Client_ptr ar_cEchoClient, const char *
> as_cmd )
> {
> tCDoCmdThreadInfo *lpDoCmdThreadInfo;
> Echo_Client_ptr lr_cEchoClient = Echo_Client::_duplicate(ar_cEchoClient);
> char *lpsz_cmd = CORBA::string_dup(as_cmd);
> // repackaging required for AfxBeginThread
> //
> lpDoCmdThreadInfo = new tCDoCmdThreadInfo;
lpDoCmdThreadInfo-> m_rcEchoClient = lr_cEchoClient;
lpDoCmdThreadInfo-> m_lpszcmd = lpsz_cmd;
> AfxBeginThread (DoCmdThreadProc, lpDoCmdThreadInfo);
> }
> // This is the real method body.
> //
> UINT DoCmdThreadProc(LPVOID pParam)
> {
> tCDoCmdThreadInfo* pDoCmdInfo = (tCDoCmdThreadInfo*)pParam;
> // Actual method stuff here
> // Now we're done. Callback to the client.
> // Second "foreign" thread generates protection exception here.
> //
pDoCmdInfo-> m_rcEchoClient->echoString (lsz_cmd);
> // Release duplicated obj reference
> CORBA::release (pDoCmdInfo->m_rcEchoClient);
> // Allocated by DoCMD
> delete pDoCmdInfo;
> return 0;
> }