X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org X-Eon-Dm: sj1-dm103 X-Eon-Sig: AQMoEGNQbeeKyp77OgIAAAAB,e5902c4b9f881ab8776797287eb2cadc From: bob To: cygwin AT cygwin DOT com Subject: Fifo blocking and performance issues - some more code snips Date: Thu, 04 Oct 2012 15:46:17 -0400 Message-ID: <2229037.KBDcDZC6oz@bob-kubuntu> User-Agent: KMail/4.8.5 (Linux/3.2.0-31-generic; KDE/4.8.5; x86_64; ; ) MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.7.7855,1.0.431,0.0.0000 definitions=2012-10-04_05:2012-10-04,2012-10-04,1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 ipscore=0 suspectscore=1 phishscore=0 bulkscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=6.0.2-1203120001 definitions=main-1210040221 Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com 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 #include #include #include #include #include #include #include #include #include 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 #include #include #include #include #include #include #include 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