Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread Peter Dufault

 1. initializes some UI goo (but doesn't start any of it UP) using a
 GUI framework (Qt)
 2. creates a FIFO, and then spawns a thread
 3. this new thread then does:
 
 fifo = open(fifoPath, O_RDONLY);

...

 
 Now, the problem is that when step 3 above blocks on the open(2)
 call (as it should, since the other end of the pipe isn't opened yet),
 the whole application is frozen, and the main thread can't continue
 with GUI processing, and the app appears to die.
 
 What is goofy is that this works just fine under Linux.  So,
 FreeBSD has slightly different blocking rules or something -- but I
 don't understand them.  It also hangs under Solaris 8/Intel.
 
 So, the question is:  how can I find out what these differences are
 and try to get around them.   I'm using this to limit instances of my
 program to one, and need a named pipe instead of just a lock file so
 that new instances can communicate any arguments they might have been
 given, etc ...  

I think the FreeBSD behavior is wrong, the spec says that when
opening a FIFO with O_NONBLOCK clear that:

 An open() for reading-only shall block the calling thread until a
 thread opens the file for writing.  An open() for writing-only
 shall block the calling thread until a thread opens the file for
 reading.

The FBSD man pages will let you know if something will block or
not, for example, look at the "implementation notes" section for
open.

You can open the fifo non-blocking and then clear O_NONBLOCK using
fcntl, hopefully that will work in all environments.

Peter

--
Peter Dufault ([EMAIL PROTECTED])   Realtime development, Machine control,
HD Associates, Inc.   Fail-Safe systems, Agency approval

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread mouss

At 17:21 26/02/01 -0800, Marc W wrote:
hello!

 I'm running into a problem with some threading using pthreads in an
application i'm writing for FreeBSD.

 The application basically

 1. initializes some UI goo (but doesn't start any of it UP) using a
GUI framework (Qt)
 2. creates a FIFO, and then spawns a thread
 3. this new thread then does:

 fifo = open(fifoPath, O_RDONLY);

 4. after the new thread is spawned, the application is supposed to
then continue initialization, showing the main window and continuing on
happily.


 Now, the problem is that when step 3 above blocks on the open(2)
call (as it should, since the other end of the pipe isn't opened yet),
the whole application is frozen, and the main thread can't continue
with GUI processing, and the app appears to die.

 What is goofy is that this works just fine under Linux.  So,
FreeBSD has slightly different blocking rules or something -- but I
don't understand them.  It also hangs under Solaris 8/Intel.

 So, the question is:  how can I find out what these differences are
and try to get around them.   I'm using this to limit instances of my
program to one, and need a named pipe instead of just a lock file so
that new instances can communicate any arguments they might have been
given, etc ...


 any suggestions?

depens on how long it blocks? is it indefinitely blocking or for some time?
in the latter, you might use a sleep() in the child before the open().
Does the parent wait for its child (the thread that does the open fifo thing)?

can you provided a small piece of code that shows this behaviour?

cheers,
mouss


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread Peter Dufault

 can you provided a small piece of code that shows this behaviour?

Here's one without error checking.  Be sure to use -pthread.

Peter

--
Peter Dufault ([EMAIL PROTECTED])   Realtime development, Machine control,
HD Associates, Inc.   Fail-Safe systems, Agency approval


#include unistd.h

#include sys/stat.h
#include sys/types.h

#include fcntl.h
#include pthread.h
#include stdio.h

struct threadstuff {
int rfid, wfid;
const char *name;
};

static void *
reader(void *arg) {
struct threadstuff *pts = (struct threadstuff *)arg;

fprintf(stderr, "Opening %s for read...", pts-name);
pts-rfid = open(pts-name, O_RDONLY);
fprintf(stderr, " reader got fid %d.\n", pts-rfid);

return 0;
}

static void *
writer(void *arg) {
struct threadstuff *pts = (struct threadstuff *)arg;

fprintf(stderr, "Opening %s for write...", pts-name);
pts-wfid = open(pts-name, O_WRONLY);
fprintf(stderr, " writer got fid %d.\n", pts-wfid);

return 0;
}

int
main(int ac, char *av[]) {
pthread_t r, w;
void *value;

struct threadstuff ts;

ts.name =  "./my_fifo";
ts.rfid = ts.wfid = -1;

(void)unlink(ts.name);
(void)mkfifo(ts.name, 0666);

pthread_create(r, 0, reader, (void *)ts);
pthread_create(w, 0, writer, (void *)ts);

pthread_join(r, value);
pthread_join(w, value);

if (ts.rfid != -1)
(void)close(ts.rfid);

if (ts.wfid != -1)
(void)close(ts.wfid);

return 0;
}

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread E.B. Dreger

Is this a library issue in libc_r?

I just wrote a quick test program using rfork(RFMEM|RFPROC) to
create a child thread.

I then had both the parent and the child attempt to open the pre-existing
file /tmp/blah with O_EXLOCK set.  When I specify O_NONBLOCK, the child
open() fails immediately.  When I do not specify O_NONBLOCK, the child
blocks indefinitely:

#if TRY_NONBLOCKING
# define O_ (O_NONBLOCK)
#else
# define O_ (0)
#endif

int main(int argc, char* *argv) {

thread_creation_using_rfork(RFPROC|RFTHREAD) ;

/* parent continues here */

printf("main: %d\n", open("/tmp/blah",
O_RDWR|O_EXLOCK|O_)) ;

for( ; ; ) ;

}

void childthreadproc(void *) {

/* child begins here */
/* fails for O_NONBLOCK, otherwise blocks indefinitely */

printf("child: %d\n", open("/tmp/blah",
O_RDWR|O_EXLOCK|O_)) ;

for( ; ; ) ;

}

Note that I've omitted the guts of rfork().

Therefore, it seems to me that the blocking is at the library level, not
the kernel level.  Have I missed something?


Eddy

---

Brotsman  Dreger, Inc.
EverQuick Internet / EternalCommerce Division

E-Mail: [EMAIL PROTECTED]
Phone: (316) 794-8922

---


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread E.B. Dreger

 Date: Tue, 27 Feb 2001 15:15:33 + (GMT)
 From: E.B. Dreger [EMAIL PROTECTED]
 
 Is this a library issue in libc_r?
 
 I just wrote a quick test program using rfork(RFMEM|RFPROC) to
 create a child thread.

Correction:

RFTHREAD|RFPROC

Sorry... I have RFMEM on the brain.  The pseudocode gave the correct RFXXX
flags.  (I also typed "#if" instead of "#ifdef".  FreeBSD multitasks
better than I do this morning.)

FWIW, does anyone know what Linuxthread's blocking behavior is?  The
original poster mentioned that Linux gave the desired behavior... what
about the Linuxthreads library?

Although I have written pthread applications, I prefer to do my thread
programming at a lower level; hence my use of rfork().  Hopefully the info
will be useful, though.


Eddy

---

Brotsman  Dreger, Inc.
EverQuick Internet / EternalCommerce Division

E-Mail: [EMAIL PROTECTED]
Phone: (316) 794-8922

---


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread Marc W


 
 I think the FreeBSD behavior is wrong, the spec says that when
 opening a FIFO with O_NONBLOCK clear that:

  An open() for reading-only shall block the calling thread until a
  thread opens the file for writing.  An open() for writing-only
  shall block the calling thread until a thread opens the file for
  reading.
 
 The FBSD man pages will let you know if something will block or
 not, for example, look at the "implementation notes" section for
 open.

 You can open the fifo non-blocking and then clear O_NONBLOCK using
 fcntl, hopefully that will work in all environments.

I have tried this, but it gets even weirder then:

- the call to open always succeeds right away (even when there are
no threads on the write end of the fifo)
- the immediately following call to read() also succeeds, returning
0 bytes as the number of bytes read.


it gets worse -- when i change my loop to be:

while (1) {

fifo = open(fifoPath, O_RDONLY | O_NONBLOCK);
cread = read(fifo, buf, sizeof(buf));
if (cread  0) do_something();
close(fifo);
usleep(10);
}

anybody who tries to open the write end of the fifo ends up hanging
..


argh!  i'll keep investigating...  my poor "2 hour solution to
single instancing" is going into day 3 :-)

marc.



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread mouss

It seems ther's a problem here:)

the manpage of open states " disables thread rescheduling...".
Is this the explanation?

As far as I can tell, Posix requires that some function should not
block the process, and lists open(), fcntl(), ...


Are there any pthread gurus who could give us the real truth here?

cheers,
mouss


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread Peter Dufault

 it gets worse -- when i change my loop to be:
 
 while (1) {
 
 fifo = open(fifoPath, O_RDONLY | O_NONBLOCK);
 cread = read(fifo, buf, sizeof(buf));
 if (cread  0) do_something();
 close(fifo);
 usleep(10);
 }
 
 anybody who tries to open the write end of the fifo ends up hanging
 ..

It's a little messier than I hoped.  As long as no one has opened the
FIFO for write read returns a zero with errno clear.  If you don't have
time slicing turned on for the threads you'll hang forever.

You'll have to do something like this:

#include unistd.h

#include sys/stat.h
#include sys/types.h

#include errno.h
#include fcntl.h
#include pthread.h
#include stdio.h

struct threadstuff {
int rfid, wfid;
const char *name;
};

static void *
reader(void *arg) {
int flags;
ssize_t r;
char buff[32];
int cr;

struct threadstuff *pts = (struct threadstuff *)arg;

fprintf(stderr, "Opening %s for read, non-blocking...\n", pts-name);

pts-rfid = open(pts-name, O_RDONLY | O_NONBLOCK);

fprintf(stderr, "reader got fid %d, setting to blocking...\n", pts-rfid);

(void)fcntl(pts-rfid, F_GETFL, flags);
flags = ~O_NONBLOCK;
(void)fcntl(pts-rfid, F_SETFL, flags);

fprintf(stderr, "Trying to read something from the FIFO...\n");

cr = 0;

/*
 * You better have round robin turned on here or be sure
 * the writer is of higher priority or you'll just buzz
 * away the CPU.
 */

do {
errno = 0;
r = read(pts-rfid, buff, sizeof(buff) - 1);

if (errno == 0  r == 0) {
/* No one has the FIFO open for write.
 * You should delay here (or preferably synchronize) 
 * to avoid busy waiting.
 */
cr++;
fprintf(stderr, "%s(%3d) No writer yet.\r",
((cr % 5) == 1) ? "\n" : "", cr);
}
} while (r == 0);

if (r  0) {
perror("Read of FIFO");
} else {
buff[r] = 0;
fprintf(stderr, "Read \"%s\".\n", buff);
}

return 0;
}

static void *
writer(void *arg) {
char something[] = "Something";

struct threadstuff *pts = (struct threadstuff *)arg;

fprintf(stderr, "Opening %s for write\n", pts-name);

pts-wfid = open(pts-name, O_WRONLY);

fprintf(stderr, "writer got fid %d.\n", pts-wfid);

write(pts-wfid, something, sizeof(something));

return 0;
}

int
main(int ac, char *av[]) {
pthread_t r, w;
void *value;

struct threadstuff ts;

ts.name =  "./my_fifo";
ts.rfid = ts.wfid = -1;

(void)unlink(ts.name);
(void)mkfifo(ts.name, 0666);

pthread_create(r, 0, reader, (void *)ts);
pthread_create(w, 0, writer, (void *)ts);

pthread_join(r, value);
pthread_join(w, value);

if (ts.rfid != -1)
(void)close(ts.rfid);

if (ts.wfid != -1)
(void)close(ts.wfid);

return 0;
}

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread Marc W


just did some more testing -- the problem does appear to be FreeBSD
specific.  Solaris 8 and all the Linuxes I've got handy run this no
probs.  Don't have any openbsd or netbsd to test those out ...

I'll just #ifdef in some code for FreeBSD.  anybody know what
#ifdef I should use before I start digging through headers?

thanks :-)

marc.



 -
 From:  mouss [EMAIL PROTECTED]
 To:  Peter Dufault [EMAIL PROTECTED]
 Cc:  Marc W [EMAIL PROTECTED], [EMAIL PROTECTED]

 Subject:  Re: Where can I find out rules on blocking in threads?
 Sent:  02/27/01 22:04 
 
 
 It seems ther's a problem here:)
 
 the manpage of open states " disables thread rescheduling...".
 Is this the explanation?
 
 As far as I can tell, Posix requires that some function should not
 block the process, and lists open(), fcntl(), ...
 
 
 Are there any pthread gurus who could give us the real truth here?
 
 cheers,
 mouss
 
 
 To Unsubscribe: send mail to [EMAIL PROTECTED]
 with "unsubscribe freebsd-hackers" in the body of the message
 


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Where can I find out rules on blocking in threads?

2001-02-27 Thread Dave Smith

Well, my understand (limited) of *BSD's threading systems is that
they are not truly pre-emptive -- they use a scheme similar to PTH
for forcing a single process to jump around its process space. Given
this, it doesn't suprise me that a few system calls don't yield; 
possibly because they aren't wrapped properly; or maybe can't be wrapped.

Of course, this is based on my _very_ limited knowledge... :)

D.

On Tue, Feb 27, 2001 at 01:43:41PM -0800, Marc W wrote:
 
 just did some more testing -- the problem does appear to be FreeBSD
 specific.  Solaris 8 and all the Linuxes I've got handy run this no
 probs.  Don't have any openbsd or netbsd to test those out ...
 
 I'll just #ifdef in some code for FreeBSD.  anybody know what
 #ifdef I should use before I start digging through headers?
 
 thanks :-)
 
 marc.
 
 
 
  -
  From:  mouss [EMAIL PROTECTED]
  To:  Peter Dufault [EMAIL PROTECTED]
  Cc:  Marc W [EMAIL PROTECTED], [EMAIL PROTECTED]
 
  Subject:  Re: Where can I find out rules on blocking in threads?
  Sent:  02/27/01 22:04 
  
  
  It seems ther's a problem here:)
  
  the manpage of open states " disables thread rescheduling...".
  Is this the explanation?
  
  As far as I can tell, Posix requires that some function should not
  block the process, and lists open(), fcntl(), ...
  
  
  Are there any pthread gurus who could give us the real truth here?
  
  cheers,
  mouss
  
  
  To Unsubscribe: send mail to [EMAIL PROTECTED]
  with "unsubscribe freebsd-hackers" in the body of the message
  
 
 
 To Unsubscribe: send mail to [EMAIL PROTECTED]
 with "unsubscribe freebsd-hackers" in the body of the message

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message