Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Side by Side Diff: fusl/src/thread/sem_open.c

Issue 1714623002: [fusl] clang-format fusl (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: headers too Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #include <semaphore.h> 1 #include <semaphore.h>
2 #include <sys/mman.h> 2 #include <sys/mman.h>
3 #include <limits.h> 3 #include <limits.h>
4 #include <fcntl.h> 4 #include <fcntl.h>
5 #include <unistd.h> 5 #include <unistd.h>
6 #include <string.h> 6 #include <string.h>
7 #include <stdarg.h> 7 #include <stdarg.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <time.h> 9 #include <time.h>
10 #include <stdio.h> 10 #include <stdio.h>
11 #include <sys/stat.h> 11 #include <sys/stat.h>
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include <pthread.h> 13 #include <pthread.h>
14 #include "libc.h" 14 #include "libc.h"
15 15
16 char *__shm_mapname(const char *, char *); 16 char* __shm_mapname(const char*, char*);
17 17
18 static struct { 18 static struct {
19 » ino_t ino; 19 ino_t ino;
20 » sem_t *sem; 20 sem_t* sem;
21 » int refcnt; 21 int refcnt;
22 } *semtab; 22 } * semtab;
23 static volatile int lock[2]; 23 static volatile int lock[2];
24 24
25 #define FLAGS (O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK) 25 #define FLAGS (O_RDWR | O_NOFOLLOW | O_CLOEXEC | O_NONBLOCK)
26 26
27 sem_t *sem_open(const char *name, int flags, ...) 27 sem_t* sem_open(const char* name, int flags, ...) {
28 { 28 va_list ap;
29 » va_list ap; 29 mode_t mode;
30 » mode_t mode; 30 unsigned value;
31 » unsigned value; 31 int fd, i, e, slot, first = 1, cnt, cs;
32 » int fd, i, e, slot, first=1, cnt, cs; 32 sem_t newsem;
33 » sem_t newsem; 33 void* map;
34 » void *map; 34 char tmp[64];
35 » char tmp[64]; 35 struct timespec ts;
36 » struct timespec ts; 36 struct stat st;
37 » struct stat st; 37 char buf[NAME_MAX + 10];
38 » char buf[NAME_MAX+10];
39 38
40 » if (!(name = __shm_mapname(name, buf))) 39 if (!(name = __shm_mapname(name, buf)))
41 » » return SEM_FAILED; 40 return SEM_FAILED;
42 41
43 » LOCK(lock); 42 LOCK(lock);
44 » /* Allocate table if we don't have one yet */ 43 /* Allocate table if we don't have one yet */
45 » if (!semtab && !(semtab = calloc(sizeof *semtab, SEM_NSEMS_MAX))) { 44 if (!semtab && !(semtab = calloc(sizeof *semtab, SEM_NSEMS_MAX))) {
46 » » UNLOCK(lock); 45 UNLOCK(lock);
47 » » return SEM_FAILED; 46 return SEM_FAILED;
48 » } 47 }
49 48
50 » /* Reserve a slot in case this semaphore is not mapped yet; 49 /* Reserve a slot in case this semaphore is not mapped yet;
51 » * this is necessary because there is no way to handle 50 * this is necessary because there is no way to handle
52 » * failures after creation of the file. */ 51 * failures after creation of the file. */
53 » slot = -1; 52 slot = -1;
54 » for (cnt=i=0; i<SEM_NSEMS_MAX; i++) { 53 for (cnt = i = 0; i < SEM_NSEMS_MAX; i++) {
55 » » cnt += semtab[i].refcnt; 54 cnt += semtab[i].refcnt;
56 » » if (!semtab[i].sem && slot < 0) slot = i; 55 if (!semtab[i].sem && slot < 0)
57 » } 56 slot = i;
58 » /* Avoid possibility of overflow later */ 57 }
59 » if (cnt == INT_MAX || slot < 0) { 58 /* Avoid possibility of overflow later */
60 » » errno = EMFILE; 59 if (cnt == INT_MAX || slot < 0) {
61 » » UNLOCK(lock); 60 errno = EMFILE;
62 » » return SEM_FAILED; 61 UNLOCK(lock);
63 » } 62 return SEM_FAILED;
64 » /* Dummy pointer to make a reservation */ 63 }
65 » semtab[slot].sem = (sem_t *)-1; 64 /* Dummy pointer to make a reservation */
66 » UNLOCK(lock); 65 semtab[slot].sem = (sem_t*)-1;
66 UNLOCK(lock);
67 67
68 » flags &= (O_CREAT|O_EXCL); 68 flags &= (O_CREAT | O_EXCL);
69 69
70 » pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); 70 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
71 71
72 » /* Early failure check for exclusive open; otherwise the case 72 /* Early failure check for exclusive open; otherwise the case
73 » * where the semaphore already exists is expensive. */ 73 * where the semaphore already exists is expensive. */
74 » if (flags == (O_CREAT|O_EXCL) && access(name, F_OK) == 0) { 74 if (flags == (O_CREAT | O_EXCL) && access(name, F_OK) == 0) {
75 » » errno = EEXIST; 75 errno = EEXIST;
76 » » goto fail; 76 goto fail;
77 » } 77 }
78 78
79 » for (;;) { 79 for (;;) {
80 » » /* If exclusive mode is not requested, try opening an 80 /* If exclusive mode is not requested, try opening an
81 » » * existing file first and fall back to creation. */ 81 * existing file first and fall back to creation. */
82 » » if (flags != (O_CREAT|O_EXCL)) { 82 if (flags != (O_CREAT | O_EXCL)) {
83 » » » fd = open(name, FLAGS); 83 fd = open(name, FLAGS);
84 » » » if (fd >= 0) { 84 if (fd >= 0) {
85 » » » » if (fstat(fd, &st) < 0 || 85 if (fstat(fd, &st) < 0 ||
86 » » » » (map = mmap(0, sizeof(sem_t), PROT_READ|PROT _WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) { 86 (map = mmap(0, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED,
87 » » » » » close(fd); 87 fd, 0)) == MAP_FAILED) {
88 » » » » » goto fail; 88 close(fd);
89 » » » » } 89 goto fail;
90 » » » » close(fd); 90 }
91 » » » » break; 91 close(fd);
92 » » » } 92 break;
93 » » » if (errno != ENOENT) 93 }
94 » » » » goto fail; 94 if (errno != ENOENT)
95 » » } 95 goto fail;
96 » » if (!(flags & O_CREAT)) 96 }
97 » » » goto fail; 97 if (!(flags & O_CREAT))
98 » » if (first) { 98 goto fail;
99 » » » first = 0; 99 if (first) {
100 » » » va_start(ap, flags); 100 first = 0;
101 » » » mode = va_arg(ap, mode_t) & 0666; 101 va_start(ap, flags);
102 » » » value = va_arg(ap, unsigned); 102 mode = va_arg(ap, mode_t) & 0666;
103 » » » va_end(ap); 103 value = va_arg(ap, unsigned);
104 » » » if (value > SEM_VALUE_MAX) { 104 va_end(ap);
105 » » » » errno = EINVAL; 105 if (value > SEM_VALUE_MAX) {
106 » » » » goto fail; 106 errno = EINVAL;
107 » » » } 107 goto fail;
108 » » » sem_init(&newsem, 1, value); 108 }
109 » » } 109 sem_init(&newsem, 1, value);
110 » » /* Create a temp file with the new semaphore contents 110 }
111 » » * and attempt to atomically link it as the new name */ 111 /* Create a temp file with the new semaphore contents
112 » » clock_gettime(CLOCK_REALTIME, &ts); 112 * and attempt to atomically link it as the new name */
113 » » snprintf(tmp, sizeof(tmp), "/dev/shm/tmp-%d", (int)ts.tv_nsec); 113 clock_gettime(CLOCK_REALTIME, &ts);
114 » » fd = open(tmp, O_CREAT|O_EXCL|FLAGS, mode); 114 snprintf(tmp, sizeof(tmp), "/dev/shm/tmp-%d", (int)ts.tv_nsec);
115 » » if (fd < 0) { 115 fd = open(tmp, O_CREAT | O_EXCL | FLAGS, mode);
116 » » » if (errno == EEXIST) continue; 116 if (fd < 0) {
117 » » » goto fail; 117 if (errno == EEXIST)
118 » » } 118 continue;
119 » » if (write(fd, &newsem, sizeof newsem) != sizeof newsem || fstat( fd, &st) < 0 || 119 goto fail;
120 » » (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHAR ED, fd, 0)) == MAP_FAILED) { 120 }
121 » » » close(fd); 121 if (write(fd, &newsem, sizeof newsem) != sizeof newsem ||
122 » » » unlink(tmp); 122 fstat(fd, &st) < 0 ||
123 » » » goto fail; 123 (map = mmap(0, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd,
124 » » } 124 0)) == MAP_FAILED) {
125 » » close(fd); 125 close(fd);
126 » » e = link(tmp, name) ? errno : 0; 126 unlink(tmp);
127 » » unlink(tmp); 127 goto fail;
128 » » if (!e) break; 128 }
129 » » munmap(map, sizeof(sem_t)); 129 close(fd);
130 » » /* Failure is only fatal when doing an exclusive open; 130 e = link(tmp, name) ? errno : 0;
131 » » * otherwise, next iteration will try to open the 131 unlink(tmp);
132 » » * existing file. */ 132 if (!e)
133 » » if (e != EEXIST || flags == (O_CREAT|O_EXCL)) 133 break;
134 » » » goto fail; 134 munmap(map, sizeof(sem_t));
135 » } 135 /* Failure is only fatal when doing an exclusive open;
136 * otherwise, next iteration will try to open the
137 * existing file. */
138 if (e != EEXIST || flags == (O_CREAT | O_EXCL))
139 goto fail;
140 }
136 141
137 » /* See if the newly mapped semaphore is already mapped. If 142 /* See if the newly mapped semaphore is already mapped. If
138 » * so, unmap the new mapping and use the existing one. Otherwise, 143 * so, unmap the new mapping and use the existing one. Otherwise,
139 » * add it to the table of mapped semaphores. */ 144 * add it to the table of mapped semaphores. */
140 » LOCK(lock); 145 LOCK(lock);
141 » for (i=0; i<SEM_NSEMS_MAX && semtab[i].ino != st.st_ino; i++); 146 for (i = 0; i < SEM_NSEMS_MAX && semtab[i].ino != st.st_ino; i++)
142 » if (i<SEM_NSEMS_MAX) { 147 ;
143 » » munmap(map, sizeof(sem_t)); 148 if (i < SEM_NSEMS_MAX) {
144 » » semtab[slot].sem = 0; 149 munmap(map, sizeof(sem_t));
145 » » slot = i; 150 semtab[slot].sem = 0;
146 » » map = semtab[i].sem; 151 slot = i;
147 » } 152 map = semtab[i].sem;
148 » semtab[slot].refcnt++; 153 }
149 » semtab[slot].sem = map; 154 semtab[slot].refcnt++;
150 » semtab[slot].ino = st.st_ino; 155 semtab[slot].sem = map;
151 » UNLOCK(lock); 156 semtab[slot].ino = st.st_ino;
152 » pthread_setcancelstate(cs, 0); 157 UNLOCK(lock);
153 » return map; 158 pthread_setcancelstate(cs, 0);
159 return map;
154 160
155 fail: 161 fail:
156 » pthread_setcancelstate(cs, 0); 162 pthread_setcancelstate(cs, 0);
157 » LOCK(lock); 163 LOCK(lock);
158 » semtab[slot].sem = 0; 164 semtab[slot].sem = 0;
159 » UNLOCK(lock); 165 UNLOCK(lock);
160 » return SEM_FAILED; 166 return SEM_FAILED;
161 } 167 }
162 168
163 int sem_close(sem_t *sem) 169 int sem_close(sem_t* sem) {
164 { 170 int i;
165 » int i; 171 LOCK(lock);
166 » LOCK(lock); 172 for (i = 0; i < SEM_NSEMS_MAX && semtab[i].sem != sem; i++)
167 » for (i=0; i<SEM_NSEMS_MAX && semtab[i].sem != sem; i++); 173 ;
168 » if (!--semtab[i].refcnt) { 174 if (!--semtab[i].refcnt) {
169 » » semtab[i].sem = 0; 175 semtab[i].sem = 0;
170 » » semtab[i].ino = 0; 176 semtab[i].ino = 0;
171 » } 177 }
172 » UNLOCK(lock); 178 UNLOCK(lock);
173 » munmap(sem, sizeof *sem); 179 munmap(sem, sizeof *sem);
174 » return 0; 180 return 0;
175 } 181 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698