DWORD WINAPI read_thread(LPVOID arg) { struct xillyfifo *fifo = (struct xillyfifo*)arg; int rd_bytes, read_bytes; struct xillyinfo info; unsigned char *buf; while (1) { //Get a loan from the FIFO for zero copy FIFO write rd_bytes = fifo_request_write(fifo, &info); //May write up to this much if (rd_bytes == 0) return 0; for(buf = (unsigned char*)info.addr; rd_bytes > 0; buf += read_bytes, rd_bytes -= read_bytes) { /* You don't need to worry about non-32-bit granularity, since _read() will never return anything unaligned to the underlying channel, unless it has been requested an unaligned number of bytes. This holds for both Windows on Linux. So unless you've done something bizarre such as allocating a buffer which isn't 32-bit aligned, or chosen such a FIFO_BACKOFF, there's nothing to check. It's pretty simple to verify that the two LSBs of all variables in the foodchain are necessarily forced to 0. */ read_bytes = _read(read_fd, buf, rd_bytes);//Read up to the loan if ((read_bytes < 0) && (errno != EINTR)) { perror("read() failed"); return 0; } if (read_bytes == 0) { // Reached EOF. Quit without complaining. fifo_done(fifo); return 0; } if (read_bytes < 0) { // errno is EINTR read_bytes = 0; continue; } //printf("DEBUG: read_thread: buf %p, %X\n", buf, *buf); fifo_wrote(fifo, read_bytes);//Return loaned bytes to FIFO and alert } } }
void *read_thread(void *arg) { struct xillyfifo *fifo = arg; int do_bytes, read_bytes; struct xillyinfo info; unsigned char *buf; while (1) { do_bytes = fifo_request_write(fifo, &info); if (do_bytes == 0) return NULL; for (buf = info.addr; do_bytes > 0; buf += read_bytes, do_bytes -= read_bytes) { read_bytes = read(read_fd, buf, do_bytes); if ((read_bytes < 0) && (errno != EINTR)) { perror("read() failed"); return NULL; } if (read_bytes == 0) { // Reached EOF. Quit without complaining. fifo_done(fifo); return NULL; } if (read_bytes < 0) { // errno is EINTR read_bytes = 0; continue; } fifo_wrote(fifo, read_bytes); } } }
void *write_thread(void *arg) { struct xillyfifo *fifo = arg; int do_bytes, written_bytes; struct xillyinfo info; unsigned char *buf; while (1) { do_bytes = fifo_request_drain(fifo, &info); if (do_bytes == 0) return NULL; for (buf = info.addr; do_bytes > 0; buf += written_bytes, do_bytes -= written_bytes) { written_bytes = write(1, buf, do_bytes); if ((written_bytes < 0) && (errno != EINTR)) { perror("write() failed"); return NULL; } if (written_bytes == 0) { fprintf(stderr, "Reached write EOF (?!)\n"); fifo_done(fifo); return NULL; } if (written_bytes < 0) { // errno is EINTR written_bytes = 0; continue; } fifo_drained(fifo, written_bytes); } } }