Forgot to mention in my last code snip post that the Linux code below is the "desired" behavior of the fifos to match the existing Linux code in the SIMPL toolkit.
In this Linux code snip we open the receive end of the fifo as RDWR (without the O_NONBLOCK flag) and Linux conveniently allows that open to occur even if the other end of the fifo isn't yet there. In Cygwin this open blocks, hence the need for the O_NONBLOCK flag. Furthermore the Linux code conveniently blocks on the read() call. In Cygwin this read doesn't block (probably because it has been open O_NONBLOCK to overcome the open blocking issue) hence the need for the select() hack. I haven't had time to replicate the blocking WRONLY fifo open problem that I noticed in my SIMPL toolkit testing on Cygwin. Early indications is that this open blocks if at least one other process has opened the fifo WRONLY and remains alive. Once again the behavior on Linux is that this open doesn't block regardless of how many other processes have the fifo open WRONLY. Thanks again for all your help. bob PS. The astute reader might be asking why RDWR and not RDONLY. Turns out that RDWR fifos on Linux allow for some detection of vanished partners which helps with cleanup in such scenerios. The behavior on Cygwin is the same with RDONLY and RDWR fifos in that the open blocks until the other partner opens the fifo. PS2. The other astute reader will recognize the QNX style Send-Receive-Reply message pass in these code snips. The receiver opens a fifo RDWR and blocks on a read() waiting for an integer value. The sender opens the receiver's fifo WRONLY and submits an integer and then blocks on its own RDWR fifo waiting for a response. Meanwhile the receiver read() unblocks and reads out an integer. The receiver then submits the response integer to a WRONLY end of the sender's reply fifo. ie. a synchronous message pass. In the SIMPL toolkit this integer exchange on the fifos is used to synchronize a shared memory exchange of the actual message bytes. ========= begin sender2.c =============== #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <time.h> #include <fcntl.h> #include <errno.h> #include <sys/select.h> #include <sys/timeb.h> int blocked_read(int, char *, int); int main(int argc, char *argv[]) { char command[80]; char fifoname[80]; int fd=-1; int rfd; int i; int j; int *r; int bytesToGo; int numBytes; char buf[5]; char *p; int rc; struct timeb before; struct timeb after; int msec; printf("fifo sender starting\n"); sprintf(fifoname,"/tmp/fsender"); mkfifo(fifoname, 0666); chmod(fifoname, 0666); printf("starting receiver2\n"); sprintf(command,"./receiver2&"); rc=system(command); printf("receiver2 started\n"); sleep(2); fd=open(fifoname, O_RDWR); //fd=open(fifoname, O_RDWR|O_NONBLOCK); rfd=open("/tmp/freceiver", O_WRONLY); ftime(&before); for(j=1; j<100; j++) { printf("j=%d\n",j); write(rfd,&j,sizeof(int)); numBytes=0; memset(buf,0,4); p=buf; for(i=0; i< 10; i++) { bytesToGo=sizeof(int) - numBytes; printf("bytesToGo=%d numBytes=%d\n",bytesToGo,numBytes); if(bytesToGo <= 0) break; rc=blocked_read(fd,p,bytesToGo); printf("sender rc[%d]=%d\n",i,rc); if(rc == 0) { printf("got eof\n"); } else if(rc == -1) { printf("%s\n",strerror(errno)); } else { numBytes+=rc; p+=rc; } } //end for i printf("buf: 0x%X-%X-%X-%X\n",buf[0],buf[1],buf[2],buf[3]); r=(int *)buf; printf("reply[%d]=%d\n",j,*r); } // end for j ftime(&after); msec=(after.time - before.time)*1000 + (after.millitm - before.millitm); printf("%d messages took %d ms\n",j, msec); sleep(1); unlink(fifoname); unlink("/tmp/freceiver"); exit(0); } // end sender int blocked_read(int fd, char *buff, int size) { int rc; //fd_set inset; //FD_ZERO(&inset); //FD_SET(fd, &inset); //printf("send: before select\n"); //select(fd+1, &inset, NULL, NULL, NULL); printf("send: before read\n"); rc=read(fd,buff,size); printf("send: read rc=%d\n",rc); return(rc); } // end blocked_read ========= end sender2.c ================ ========== begin receiver2.c =========== #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <sys/select.h> int blocked_read(int, char *, int); int main(int argc, char *argv[]) { char command[80]; char fifoname[80]; int fd; int rfd; int dummy; int i; int j; int k; int *r; int bytesToGo; int numBytes; char buf[4]; char *p; int rc; printf("fifo receiver starting\n"); sprintf(fifoname,"/tmp/freceiver"); mkfifo(fifoname, 0666); chmod(fifoname, 0666); fd=open(fifoname, O_RDWR); //fd=open(fifoname, O_RDWR | O_NONBLOCK); for(k=0; k<99; k++) { numBytes=0; p=buf; for(i=0; i< 10; i++) { bytesToGo=sizeof(int) - numBytes; if(bytesToGo <= 0) break; // rc=read(fd,p,bytesToGo); rc=blocked_read(fd,p,bytesToGo); printf("recv rc[%d]=%d\n",i,rc); if(rc == 0) { printf("recv eof\n"); } else if(rc == -1) { printf("%s\n",strerror(errno)); } else { numBytes+=rc; p+=rc; } } // end for i r=(int *)buf; j=*r; printf("received[%d]=%d\n",k,j); j++; // sleep(1); rfd=open("/tmp/fsender", O_WRONLY); write(rfd,&j,sizeof(int)); close(rfd); } // end for k unlink(fifoname); exit(0); } // end receiver int blocked_read(int fd, char *buff, int size) { int rc; //fd_set inset; //FD_ZERO(&inset); //FD_SET(fd, &inset); //printf("recv: before select\n"); //select(fd+1, &inset, NULL, NULL, NULL); printf("recv: before read\n"); rc=read(fd,buff,size); printf("recv: read rc=%d\n",rc); return(rc); } // end blocked_read ========== end receiver2.c ============= ========= begin linux.out2 ============= sender2 fifo sender starting starting receiver2 receiver2 started fifo receiver starting recv: before read j=1 bytesToGo=4 numBytes=0 send: before read recv: read rc=4 recv rc[0]=4 received[0]=1 recv: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x2-0-0-0 reply[1]=2 j=2 bytesToGo=4 numBytes=0 send: before read recv: read rc=4 recv rc[0]=4 received[1]=2 recv: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x3-0-0-0 reply[2]=3 j=3 bytesToGo=4 numBytes=0 send: before read recv: read rc=4 recv rc[0]=4 received[2]=3 recv: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x4-0-0-0 reply[3]=4 j=4 bytesToGo=4 numBytes=0 send: before read recv: read rc=4 recv rc[0]=4 received[3]=4 recv: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x5-0-0-0 reply[4]=5 j=5 bytesToGo=4 numBytes=0 send: before read recv: read rc=4 recv rc[0]=4 received[4]=5 recv: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x6-0-0-0 reply[5]=6 ... j=92 bytesToGo=4 numBytes=0 recv: read rc=4 recv rc[0]=4 received[91]=92 recv: before read send: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x5D-0-0-0 reply[92]=93 j=93 bytesToGo=4 numBytes=0 recv: read rc=4 recv rc[0]=4 received[92]=93 recv: before read send: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x5E-0-0-0 reply[93]=94 j=94 bytesToGo=4 numBytes=0 recv: read rc=4 recv rc[0]=4 received[93]=94 recv: before read send: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x5F-0-0-0 reply[94]=95 j=95 bytesToGo=4 numBytes=0 recv: read rc=4 recv rc[0]=4 received[94]=95 recv: before read send: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x60-0-0-0 reply[95]=96 j=96 bytesToGo=4 numBytes=0 recv: read rc=4 recv rc[0]=4 received[95]=96 recv: before read send: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x61-0-0-0 reply[96]=97 j=97 bytesToGo=4 numBytes=0 recv: read rc=4 recv rc[0]=4 received[96]=97 recv: before read send: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x62-0-0-0 reply[97]=98 j=98 bytesToGo=4 numBytes=0 recv: read rc=4 recv rc[0]=4 received[97]=98 recv: before read send: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x63-0-0-0 reply[98]=99 j=99 bytesToGo=4 numBytes=0 recv: read rc=4 recv rc[0]=4 received[98]=99 send: before read send: read rc=4 sender rc[0]=4 bytesToGo=0 numBytes=4 buf: 0x64-0-0-0 reply[99]=100 100 messages took 8 ms ========= end linux.out2 =============== -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple