github.com/schwarzm/garden-linux@v0.0.0-20150507151835-33bca2147c47/old/linux_backend/src/wsh/barrier.c (about) 1 #define _GNU_SOURCE 2 3 #include <errno.h> 4 #include <stdio.h> 5 #include <string.h> 6 #include <unistd.h> 7 8 #include "barrier.h" 9 #include "util.h" 10 11 int barrier_open(barrier_t *bar) { 12 int rv; 13 int aux[2] = { -1, -1 }; 14 15 rv = pipe(aux); 16 if (rv == -1) { 17 perror("pipe"); 18 goto err; 19 } 20 21 bar->fd[0] = aux[0]; 22 bar->fd[1] = aux[1]; 23 return 0; 24 25 err: 26 if (aux[0] >= 0) close(aux[0]); 27 if (aux[1] >= 0) close(aux[1]); 28 return -1; 29 } 30 31 void barrier_close(barrier_t *bar) { 32 close(bar->fd[0]); 33 close(bar->fd[1]); 34 } 35 36 void barrier_mix_cloexec(barrier_t *bar) { 37 fcntl_mix_cloexec(bar->fd[0]); 38 fcntl_mix_cloexec(bar->fd[1]); 39 } 40 41 void barrier_close_wait(barrier_t *bar) { 42 close(bar->fd[0]); 43 bar->fd[0] = -1; 44 } 45 46 void barrier_close_signal(barrier_t *bar) { 47 close(bar->fd[1]); 48 bar->fd[1] = -1; 49 } 50 51 int barrier_wait(barrier_t *bar) { 52 int nread; 53 char buf[1]; 54 55 barrier_close_signal(bar); 56 57 nread = read(bar->fd[0], buf, sizeof(buf)); 58 59 barrier_close_wait(bar); 60 61 if (nread == -1) { 62 perror("read"); 63 return -1; 64 } else if (nread == 0) { 65 return -1; 66 } 67 68 return 0; 69 } 70 71 int barrier_signal(barrier_t *bar) { 72 int nwritten; 73 char byte = '\0'; 74 75 barrier_close_wait(bar); 76 77 nwritten = write(bar->fd[1], &byte, 1); 78 79 barrier_close_signal(bar); 80 81 if (nwritten == -1) { 82 perror("write"); 83 return -1; 84 } 85 86 return 0; 87 }