TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: Phil Crown
from: Craig Swanson
date: 1995-10-24 12:34:12
subject: _beginthread too fast

PC> However, I have another problem with _beginthread().  In my PM terminal
 PC> program, if I don't call DosSleep(400) after calling _beginthread(), the
 PC> thread fails to start.  Anything less than 400 and the thread will not
 PC> always start, and even at 400 it sometimes doesn't
 PC> start the very first time
 PC> I call _beginthread(), but will start after the first call to
 PC> _beginthread().

 PC> Before you all dismiss this as crap... :-) consider
 PC> the following from the
 PC> Xr_W010.Rm2 APAR for fixpack #10

 PC> APAR= PJ16508
 PC>  DOSCONNECTNPIPE() FAILS ON A FAST SYSTEM WITHOUT A DOSSLEEP.

 PC> Maybe there is a similiar problem with
 PC> _beginthread()??  I'm not sure what
 PC> is considered a fast system, I'm running a 486-66 DX-S.

I'm pretty sure this is one of the APAR fixes that grew out of problems I
reported regarding named pipes in OS/2 2.1 and Warp.  Basically,the problem
was that if a process or thread did a DosOpen() on a named pipe followed
fairly quickly by a DosClose(), the server thread that was blocked on
DosConnectNPipe() would never unblock.  By putting a DosSleep() in between
the DosOpen() and DosClose(), almost always the DosConnectNPipe() call
would unblock.

Now you might wonder why on earth somebody would want to do this.  The
reason is that once the named pipe is put into blocking mode, there isn't a
good way to dislodge the server thread waiting for new connections and
blocked on DosConnectNPipe() to allow the thread to shut itself down (such
as when the server process needs to be shut down) except for using
DosOpen() to dislodge it.  But then there isn't anything to be
communicated, as this DosOpen() is being done by another thread in the
server process which has already set a flag to indicate a shutdown is
pending that the server thread will check after it unblocks from
DosConnectNPipe().

The only alternative to this appears to be avoiding the use of blocking
mode and calling DosConnectNPipe() in a loop with
a DosSleep() call to keep it from sucking up most of the CPU time. I don't
consider that to be a good solution as it still sucks up more CPU time and
also will respond to connection requests much more slowly than it would by
using DosConnectNPipe() with blocking mode.

I went round and round with IBM on this problem because all of the
computers on which they tested my test case were 486SX/25 or slower and
they could never reproduce the problem.  All of the computers on which
either I or friends ran the test case (including ones at other sites --
i.e., other OS/2 BBS computers, and even a computer at another company
writing commercial OS/2 software) reproduced the problem.  It appears that
for this problem, a "fast system" is a 486/33 or better.

Overall, I'd have to say that named pipes in OS/2 2.x and 3.0 are buggy and
apparently have a reputation within IBM of being a mess nobody wants to
touch -- maybe because they have stuck around since OS/2 1.x (yes, it's
still 16-bit code!) and may have originally been written by Microsoft.  For
example,recently I've again had problems with message fragmention such that
DosWrite() only writes a partial message into the named pipe when the pipe
is in blocking message mode. This violates the API documentation and worse
screws up the message such that it shows up as two incomplete messages on
the receiving end. This is a really hard problem to reproduce in any
reliable fashion,but I've had it happen many times in the last year and it
still isn't fixed in fixpak #10 so therefore I am about to rewrite part of
my program to use byte mode rather than message mode and am hoping this
will correct the troubles I am having.

Most of these problems I've encountered with named pipes appear to be race
conditions perhaps caused by improper use (or lack of use) of event or
mutex semaphores. Perhaps part of the reason I've run into them so much is
because of the extensive use of multithreading I've made.  However, I have
never run into a problem with threads failing to start.  So therefore at
first thought I would suspect something outside of OS/2 itself to be
causing your thread startup problem.

 PC> Here is a code snippet to show a little of how I am
 PC> calling _beginthread().
 PC> RunRexxScript calls RexxStart to run a Rexx *.cmd file.  That part works
 PC> once the thread is started.  The problem is the thread
 PC> won't start without
 PC> the call to DosSleep(400);

 PC> case IDM_SCRIPT_RUN:
 PC>     if(tidScr != 0) {
 PC>       Msg(0, ProgName, "Script already running\nAbort
 PC> current script first");
 PC>       break;
 PC>     }
 PC>     rc = SelectRexxScript(pdata, fname); // FileDlg to select *.cmd file
 PC>     if(rc == TRUE) {
 PC>       tidScr = _beginthread(RunRexxScript, 16384, (PVOID)fname);

Are you sure your parameters (especially fname) are valid?
Where is fname declared -- for example, could it have been
deallocated or modified by another thread?  If this code snippet is inside
a PM message handler function, the DosSleep() could
change the timing of processing a message after IDM_SCRIPT_RUN that would
affect the data being used by the RunRexxScript
thread before it has a chance to use it.

Are you using Borland C++?  If so, maybe there's a bug in their runtime
library.  The _beginthread() function is a C/C++ runtime function, not an
OS/2 API.

How is "not starting" being indicated?  Do you get a 0xFFFF
return value?  Or does the function return a thread ID, but the thread
doesn't appear to run?

What other threads are running in your process when this problem happens
and what are those threads doing?  I'm wondering if _beginthread() in your
case is trying to get mutex on a runtime library data structure but is
failing to do so before a timeout occurs.

 PC>       if(tidScr == 0xffff) {
 PC>         Msg(0, ProgName, "%s %d\nError starting script thread",
 PC>         __FILE__, __LINE__);
 PC>         tidScr = 0;
 PC>       }
 PC>       else
 PC>         DosSleep(400);  // without this the thread won't start
 PC>     }
 PC>     break;

From this, it looks like you get a TID that is not 0xFFFF, but the thread
doesn't start.  How are you determining if the thread is or is not
starting? Can you write something to stdout (or to a file) at the start of
the thread and see if this shows up?  Maybe the thread has started and has
gotten stuck or screwed up somehow?


--- Maximus/2 2.02
* Origin: OS/2 Connection {at} Mira Mesa, CA (1:202/354)
SEEN-BY: 270/101 620/243 711/401 409 410 413 430 807 808 809 934 955 712/407
SEEN-BY: 712/515 628 704 713/888 800/1 7877/2809
@PATH: 202/354 300 777 3615/50 396/1 270/101 712/515 711/808 809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.