Branch Coverage

sync.h
Criterion Covered Total %
branch 291 606 48.0


line true false branch
147 0 1 if (pid == 0) return 1;
148 1 0 return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH);
0 1 return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH);
156 1 16 if (deadline->tv_nsec >= 1000000000L) {
169 10 8 if (remaining->tv_nsec < 0) {
187 0 0 if (!__atomic_compare_exchange_n(&hdr->mutex, &observed, 0,
191 0 0 if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0)
199 15 0 if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid,
202 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
208 0 0 if (cur != 0) {
211 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
214 0 0 if (val >= SYNC_MUTEX_WRITER_BIT) {
216 0 0 if (!sync_pid_alive(pid))
230 0 16 if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0)
250 0 0 if (!__atomic_compare_exchange_n(&hdr->value, &observed, 0,
254 0 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
274 0 20 if (!h->reader_slots) return;
277 0 20 if (h->cached_fork_gen != cur_gen) {
281 12 8 if (h->my_slot_idx != UINT32_MAX) return;
285 8 0 for (uint32_t i = 0; i < SYNC_READER_SLOTS; i++) {
288 8 0 if (__atomic_compare_exchange_n(&h->reader_slots[s].pid,
304 0 0 if (!sub) return;
307 0 0 uint32_t want = (cur > sub) ? cur - sub : 0;
308 0 0 if (__atomic_compare_exchange_n(p, &cur, want,
321 0 0 if (!__atomic_compare_exchange_n(&h->reader_slots[i].pid, &expected, 0,
327 0 0 if (wp) { sync_atomic_sub_cap(&hdr->waiters, wp); drained = 1; }
328 0 0 if (writp) { sync_atomic_sub_cap(&hdr->rwlock_writers_waiting, writp); drained = 1; }
335 0 0 if (!h->reader_slots) return;
345 0 0 for (uint32_t i = 0; i < SYNC_READER_SLOTS; i++) {
347 0 0 if (pid == 0) continue;
349 0 0 if (sync_pid_alive(pid)) {
350 0 0 if (sc > 0) any_live_reader = 1;
353 0 0 if (sc > 0) { found_dead_reader = 1; continue; }
354 0 0 if (sync_drain_dead_slot(h, i, pid)) any_recovery = 1;
360 0 0 if (found_dead_reader && !any_live_reader) {
0 0 if (found_dead_reader && !any_live_reader) {
362 0 0 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
0 0 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
363 0 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, 0,
366 0 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
370 0 0 for (uint32_t i = 0; i < SYNC_READER_SLOTS; i++) {
372 0 0 if (pid == 0) continue;
373 0 0 if (sync_pid_alive(pid)) continue;
374 0 0 if (sync_drain_dead_slot(h, i, pid)) any_recovery = 1;
377 0 0 if (any_recovery)
385 1 0 if (h->my_slot_idx != UINT32_MAX)
390 1 0 if (h->my_slot_idx != UINT32_MAX)
396 1 0 if (h->my_slot_idx != UINT32_MAX) {
404 1 0 if (h->my_slot_idx != UINT32_MAX) {
421 0 0 if (val >= SYNC_RWLOCK_WRITER_BIT) {
423 0 0 if (!sync_pid_alive(pid))
437 7 0 if (h->my_slot_idx != UINT32_MAX)
442 1 6 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
1 0 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
443 1 0 if (__atomic_compare_exchange_n(lock, &cur, cur + 1,
446 6 0 } else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) {
6 0 } else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) {
447 6 0 if (__atomic_compare_exchange_n(lock, &cur, 1,
451 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
458 0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) {
0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) {
461 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
463 0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT) {
470 0 0 while (wc > 0 && !__atomic_compare_exchange_n(
471 0 0 writers_waiting, &wc, wc - 1,
496 0 3 if (timeout == 0) {
505 3 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
509 3 0 if (h->my_slot_idx != UINT32_MAX)
515 33 2 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
0 33 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
516 0 0 if (__atomic_compare_exchange_n(lock, &cur, cur + 1,
519 2 33 } else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) {
2 0 } else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) {
520 2 0 if (__atomic_compare_exchange_n(lock, &cur, 1,
524 32 1 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
530 0 1 if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) {
0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) {
535 1 0 if (has_deadline) {
536 0 1 if (!sync_remaining_time(&deadline, &remaining)) {
538 0 0 if (h->my_slot_idx != UINT32_MAX)
542 0 1 if (remaining.tv_sec >= SYNC_LOCK_TIMEOUT_SEC) {
553 1 0 if (rc == -1 && errno == ETIMEDOUT) {
1 0 if (rc == -1 && errno == ETIMEDOUT) {
558 1 0 if (!capped) {
559 1 0 if (h->my_slot_idx != UINT32_MAX)
563 0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT) {
569 0 0 while (wc > 0 && !__atomic_compare_exchange_n(
570 0 0 writers_waiting, &wc, wc - 1,
589 3 0 if (h->my_slot_idx != UINT32_MAX)
592 1 2 if (cur >= SYNC_RWLOCK_WRITER_BIT) {
593 1 0 if (h->my_slot_idx != UINT32_MAX)
597 2 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur + 1,
600 0 0 if (h->my_slot_idx != UINT32_MAX)
611 12 0 if (h->my_slot_idx != UINT32_MAX)
613 10 2 if (prev == 0 && __atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
0 10 if (prev == 0 && __atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
624 5 0 if (__atomic_compare_exchange_n(lock, &expected, mypid,
627 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
633 0 0 if (cur != 0) {
636 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
650 3 1 if (sync_rwlock_try_wrlock(h)) return 1;
651 0 1 if (timeout == 0) return 0;
659 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
663 0 33 if (__atomic_compare_exchange_n(lock, &expected, mypid,
666 32 1 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
672 1 0 if (cur != 0) {
677 1 0 if (has_deadline) {
678 0 1 if (!sync_remaining_time(&deadline, &remaining)) {
682 0 1 if (remaining.tv_sec >= SYNC_LOCK_TIMEOUT_SEC) {
693 1 0 if (rc == -1 && errno == ETIMEDOUT) {
1 0 if (rc == -1 && errno == ETIMEDOUT) {
695 1 0 if (!capped) return 0; /* user deadline expired */
717 0 8 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
727 1 0 if (h->my_slot_idx != UINT32_MAX)
730 0 1 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
745 5 24 if (cur == 0) return 0;
746 24 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - 1,
755 1 9 if (n == 0) return 1;
759 4 5 if (cur < n) return 0;
760 5 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - n,
769 0 3 if (n == 0) return 1;
770 2 1 if (sync_sem_try_acquire_n(h, n)) return 1;
771 0 1 if (timeout == 0) return 0;
776 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
782 0 1 if (cur >= n) {
783 0 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - n,
794 1 0 if (has_deadline) {
795 0 1 if (!sync_remaining_time(&deadline, &remaining)) {
806 0 1 if (sync_sem_try_acquire_n(h, n)) return 1;
808 1 0 if (has_deadline) {
809 1 0 if (!sync_remaining_time(&deadline, &remaining)) {
818 2 2 if (sync_sem_try_acquire(h)) return 1;
819 1 1 if (timeout == 0) return 0;
824 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
830 0 1 if (cur > 0) {
831 0 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - 1,
842 1 0 if (has_deadline) {
843 0 1 if (!sync_remaining_time(&deadline, &remaining)) {
855 0 1 if (sync_sem_try_acquire(h)) return 1;
857 1 0 if (has_deadline) {
858 1 0 if (!sync_remaining_time(&deadline, &remaining)) {
872 1 6 if (next > max_val) next = max_val; /* clamp at max */
873 7 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, next,
876 0 7 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
884 1 9 if (n == 0) return;
889 8 1 uint32_t next = (n > max_val - cur) ? max_val : cur + n;
890 9 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, next,
893 0 9 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) {
906 1 3 if (cur == 0) return 0;
936 1 8 if (timeout == 0) return -1; /* non-blocking probe: can't rendezvous instantly */
939 1 7 if (gen_raw & SYNC_BARRIER_BROKEN_BIT) return -1; /* already broken */
943 0 7 if (arrived == parties) {
948 0 0 if (old_g & SYNC_BARRIER_BROKEN_BIT) {
950 0 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
955 0 0 if (__atomic_compare_exchange_n(&hdr->generation, &old_g, new_g,
960 0 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
970 7 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
974 0 14 if (cur_raw & SYNC_BARRIER_BROKEN_BIT) return -1; /* broken */
975 5 9 if (cur_raw != gen_raw) return 0; /* barrier tripped */
980 9 0 if (has_deadline) {
981 2 7 if (!sync_remaining_time(&deadline, &remaining)) {
990 0 2 gen_raw | SYNC_BARRIER_BROKEN_BIT,
992 0 0 && !(g & SYNC_BARRIER_BROKEN_BIT)) {
1027 2 0 if (__atomic_compare_exchange_n(&hdr->generation, &old_g, new_g,
1031 0 2 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
1057 1 0 if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid,
1070 1 3 if (timeout == 0) return 0; /* non-blocking: no wait */
1080 3 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
1085 0 3 if (cur != seq) { signaled = 1; break; }
1090 3 0 if (has_deadline) {
1091 0 3 if (!sync_remaining_time(&deadline, &remaining)) {
1103 1 2 if (cur != seq) { signaled = 1; break; }
1105 2 0 if (rc == -1 && errno == ETIMEDOUT && has_deadline) {
2 0 if (rc == -1 && errno == ETIMEDOUT && has_deadline) {
2 0 if (rc == -1 && errno == ETIMEDOUT && has_deadline) {
1120 1 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
1128 1 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
1155 4 4 if (__atomic_compare_exchange_n(&hdr->value, &expected, mypid,
1160 1 3 if (expected == SYNC_ONCE_DONE) return 0;
1171 3 3 if (r == 1) return 1;
1172 1 2 if (r == 0) return 0;
1173 1 1 if (timeout == 0) return 0;
1177 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
1183 1 1 if (r == 1) return 1; /* caller is initializer */
1184 0 1 if (r == 0) return 0; /* already done */
1188 0 1 if (val == SYNC_ONCE_DONE) return 0;
1189 0 1 if (val == SYNC_ONCE_INIT) continue; /* race: was reset, retry */
1192 1 0 if (val >= SYNC_MUTEX_WRITER_BIT) {
1194 1 0 if (!sync_pid_alive(pid)) {
1195 1 0 if (__atomic_compare_exchange_n(&hdr->value, &val, SYNC_ONCE_INIT,
1198 0 1 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
1210 0 0 if (has_deadline) {
1211 0 0 if (!sync_remaining_time(&deadline, &remaining)) {
1216 0 0 if (remaining.tv_sec < SYNC_LOCK_TIMEOUT_SEC)
1229 1 3 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
1236 0 2 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
1255 15 60 if (type == SYNC_TYPE_RWLOCK)
1261 15 60 return (type == SYNC_TYPE_RWLOCK) ? sizeof(SyncHeader) : 0;
1266 74 0 if (errbuf) errbuf[0] = '\0';
1268 0 74 if (type > SYNC_TYPE_ONCE) { SYNC_ERR("unknown type %u", type); return NULL; }
0 0 if (type > SYNC_TYPE_ONCE) { SYNC_ERR("unknown type %u", type); return NULL; }
1269 25 49 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
1 24 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
1 0 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
1270 24 49 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
2 22 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
2 0 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
1271 13 58 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
2 11 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
2 0 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
1279 53 16 if (anonymous) {
1283 0 53 if (base == MAP_FAILED) {
1284 0 0 SYNC_ERR("mmap(anonymous): %s", strerror(errno));
1295 17 36 if (type == SYNC_TYPE_SEMAPHORE)
1302 0 16 if (fd < 0) { SYNC_ERR("open(%s): %s", path, strerror(errno)); return NULL; }
0 0 if (fd < 0) { SYNC_ERR("open(%s): %s", path, strerror(errno)); return NULL; }
1304 0 16 if (flock(fd, LOCK_EX) < 0) {
1305 0 0 SYNC_ERR("flock(%s): %s", path, strerror(errno));
1310 0 16 if (fstat(fd, &st) < 0) {
1311 0 0 SYNC_ERR("fstat(%s): %s", path, strerror(errno));
1317 9 7 if (!is_new && (uint64_t)st.st_size < sizeof(SyncHeader)) {
0 9 if (!is_new && (uint64_t)st.st_size < sizeof(SyncHeader)) {
1318 0 0 SYNC_ERR("%s: file too small (%lld)", path, (long long)st.st_size);
1322 7 9 if (is_new) {
1323 0 7 if (ftruncate(fd, (off_t)total_size) < 0) {
1324 0 0 SYNC_ERR("ftruncate(%s): %s", path, strerror(errno));
1329 9 7 map_size = is_new ? (size_t)total_size : (size_t)st.st_size;
1331 0 16 if (base == MAP_FAILED) {
1332 0 0 SYNC_ERR("mmap(%s): %s", path, strerror(errno));
1338 9 7 if (!is_new) {
1340 9 0 hdr->version == SYNC_VERSION &&
1341 9 0 hdr->type == type &&
6 3 hdr->type == type &&
1342 6 0 hdr->total_size == (uint64_t)st.st_size);
1343 6 3 if (valid && type == SYNC_TYPE_RWLOCK) {
1 5 if (valid && type == SYNC_TYPE_RWLOCK) {
1347 1 0 if (hdr->reader_slots_off != sizeof(SyncHeader) ||
1348 0 1 (uint64_t)st.st_size < need)
1351 3 6 if (!valid) {
1352 3 0 SYNC_ERR("%s: invalid or incompatible sync file", path);
1368 3 4 if (type == SYNC_TYPE_SEMAPHORE)
1380 0 66 if (!h) { munmap(base, map_size); return NULL; }
1384 13 53 h->path = path ? strdup(path) : NULL;
1389 13 53 : NULL;
1399 6 0 if (errbuf) errbuf[0] = '\0';
1401 0 6 if (type > SYNC_TYPE_ONCE) { SYNC_ERR("unknown type %u", type); return NULL; }
0 0 if (type > SYNC_TYPE_ONCE) { SYNC_ERR("unknown type %u", type); return NULL; }
1402 2 4 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
0 2 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
0 0 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
1403 2 4 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
0 2 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
0 0 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
1404 1 5 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
0 1 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
0 0 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
1409 6 0 int fd = memfd_create(name ? name : "sync", MFD_CLOEXEC | MFD_ALLOW_SEALING);
1410 0 6 if (fd < 0) { SYNC_ERR("memfd_create: %s", strerror(errno)); return NULL; }
0 0 if (fd < 0) { SYNC_ERR("memfd_create: %s", strerror(errno)); return NULL; }
1412 0 6 if (ftruncate(fd, (off_t)total_size) < 0) {
1413 0 0 SYNC_ERR("ftruncate(memfd): %s", strerror(errno));
1419 0 6 if (base == MAP_FAILED) {
1420 0 0 SYNC_ERR("mmap(memfd): %s", strerror(errno));
1433 2 4 if (type == SYNC_TYPE_SEMAPHORE)
1439 0 6 if (!h) { munmap(base, (size_t)total_size); close(fd); return NULL; }
1448 1 5 : NULL;
1455 5 0 if (errbuf) errbuf[0] = '\0';
1458 1 4 if (fstat(fd, &st) < 0) {
1459 1 0 SYNC_ERR("fstat(fd=%d): %s", fd, strerror(errno));
1463 0 4 if ((uint64_t)st.st_size < sizeof(SyncHeader)) {
1464 0 0 SYNC_ERR("fd %d: too small (%lld)", fd, (long long)st.st_size);
1470 0 4 if (base == MAP_FAILED) {
1471 0 0 SYNC_ERR("mmap(fd=%d): %s", fd, strerror(errno));
1477 4 0 hdr->version == SYNC_VERSION &&
1478 4 0 hdr->type == type &&
3 1 hdr->type == type &&
1479 3 0 hdr->total_size == (uint64_t)st.st_size);
1480 3 1 if (valid && type == SYNC_TYPE_RWLOCK) {
1 2 if (valid && type == SYNC_TYPE_RWLOCK) {
1483 1 0 if (hdr->reader_slots_off != sizeof(SyncHeader) ||
1484 0 1 (uint64_t)st.st_size < need)
1487 1 3 if (!valid) {
1488 1 0 SYNC_ERR("fd %d: invalid or incompatible sync", fd);
1494 0 3 if (myfd < 0) {
1495 0 0 SYNC_ERR("fcntl(F_DUPFD_CLOEXEC): %s", strerror(errno));
1501 0 3 if (!h) { munmap(base, map_size); close(myfd); return NULL; }
1510 1 2 : NULL;
1517 0 75 if (!h) return;
1521 15 60 if (h->reader_slots && h->my_slot_idx != UINT32_MAX && h->cached_pid &&
8 7 if (h->reader_slots && h->my_slot_idx != UINT32_MAX && h->cached_pid &&
8 0 if (h->reader_slots && h->my_slot_idx != UINT32_MAX && h->cached_pid &&
1522 8 0 h->cached_fork_gen == __atomic_load_n(&sync_fork_gen, __ATOMIC_RELAXED)) {
1531 11 64 if (h->notify_fd >= 0) close(h->notify_fd);
1532 9 66 if (h->backing_fd >= 0) close(h->backing_fd);
1533 75 0 if (h->hdr) munmap(h->hdr, h->mmap_size);
1543 0 11 if (h->notify_fd >= 0) return h->notify_fd;
1545 0 11 if (efd < 0) return -1;
1551 0 10 if (h->notify_fd < 0) return 0;
1557 0 11 if (h->notify_fd < 0) return -1;
1559 5 6 if (read(h->notify_fd, &val, sizeof(val)) != sizeof(val)) return -1;