comm.c (2506B)
1 #include "mxf-send.h" 2 /* this file is too long ------------------------------------- COMMUNICATION */ 3 4 // Why's cleanup a separate function? it should just be a channel... 5 substdio sstoqc; 6 char sstoqcbuf[1024]; 7 substdio ssfromqc; 8 char ssfromqcbuf[1024]; 9 10 stralloc comm_buf[CHANNELS] = {{0}, {0}}; 11 int comm_pos[CHANNELS]; 12 13 void 14 comm_init() 15 { 16 int c; 17 // special casing... 18 // this also relies on those FDs being, well... 19 substdio_fdbuf(&sstoqc, write, 5, sstoqcbuf, sizeof(sstoqcbuf)); 20 substdio_fdbuf(&ssfromqc, read, 6, ssfromqcbuf, sizeof(ssfromqcbuf)); 21 for (c = 0; c < CHANNELS; ++c) 22 if (ndelay_on(chanfdout[c]) == -1) 23 /* 24 * this is so stupid: NDELAY semantics should be 25 * default on write 26 */ 27 spawndied(c); /* drastic, but better than risking 28 * deadlock */ 29 } 30 31 int 32 comm_canwrite(int c) 33 { 34 /* XXX: could allow a bigger buffer; say 10 recipients */ 35 if (comm_buf[c].s && comm_buf[c].len) 36 return 0; 37 return 1; 38 } 39 40 void 41 comm_write(int c, int delnum, unsigned long id, char *sender, char *recip) 42 { 43 char ch; 44 if (comm_buf[c].s && comm_buf[c].len) 45 return; 46 while (!stralloc_copys(&comm_buf[c], "")) 47 nomem(); 48 ch = delnum; 49 while (!stralloc_append(&comm_buf[c], &ch)) 50 nomem(); 51 fnmake_split(id, &fn); 52 while (!stralloc_cats(&comm_buf[c], fn.s)) 53 nomem(); 54 while (!stralloc_0(&comm_buf[c])) 55 nomem(); 56 senderadd(&comm_buf[c], sender, recip); 57 while (!stralloc_0(&comm_buf[c])) 58 nomem(); 59 while (!stralloc_cats(&comm_buf[c], recip)) 60 nomem(); 61 while (!stralloc_0(&comm_buf[c])) 62 nomem(); 63 comm_pos[c] = 0; 64 } 65 66 void 67 comm_selprep(int *nfds, fd_set * wfds) 68 { 69 int c; 70 for (c = 0; c < CHANNELS; ++c) 71 if (flagspawnalive[c]) 72 if (comm_buf[c].s && comm_buf[c].len) { 73 FD_SET(chanfdout[c], wfds); // if we had iolib, we could do this better. 74 if (*nfds <= chanfdout[c]) 75 *nfds = chanfdout[c] + 1; 76 } 77 } 78 79 void 80 comm_do(fd_set * wfds) 81 { 82 int c; 83 for (c = 0; c < CHANNELS; ++c) 84 if (flagspawnalive[c]) 85 if (comm_buf[c].s && comm_buf[c].len) 86 if (FD_ISSET(chanfdout[c], wfds)) { 87 int w; // isn't this just a nonblocking substdio?! 88 int len; 89 len = comm_buf[c].len; 90 w = write(chanfdout[c], comm_buf[c].s + comm_pos[c], len - comm_pos[c]); 91 if (w == 0 || w == -1) { 92 if ((w == -1) && (errno == error_pipe)) 93 spawndied(c); 94 else 95 continue; /* kernel select() bug; 96 * can't avoid 97 * busy-looping */ 98 } else { 99 comm_pos[c] += w; 100 if (comm_pos[c] == len) 101 comm_buf[c].len = 0; 102 } 103 } 104 }