Skip to content

Commit e493d03

Browse files
Copilotenghitalo
andcommitted
Add comprehensive documentation and improve test comments
Co-authored-by: enghitalo <63821277+enghitalo@users.noreply.github.com>
1 parent ba7b90b commit e493d03

4 files changed

Lines changed: 111 additions & 1 deletion

File tree

vlib/os/notify/README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# os.notify - File Descriptor Event Notification
2+
3+
The `os.notify` module provides cross-platform file descriptor event notification using the best available mechanism for each platform:
4+
- **Linux**: epoll
5+
- **macOS/BSD**: kqueue
6+
- **Other platforms**: Not yet supported
7+
8+
## Usage
9+
10+
```v
11+
import os
12+
import os.notify
13+
14+
mut notifier := notify.new()!
15+
defer {
16+
notifier.close() or {}
17+
}
18+
19+
// Add a file descriptor to watch for read events
20+
notifier.add(fd, .read)!
21+
22+
// Wait for events (with timeout)
23+
events := notifier.wait(100 * time.millisecond)
24+
for event in events {
25+
if event.kind.has(.read) {
26+
// Handle read event
27+
}
28+
}
29+
```
30+
31+
## Event Types
32+
33+
- `.read` - Data is available to read
34+
- `.write` - File descriptor is ready for writing
35+
- `.peer_hangup` - Peer closed the connection (Linux only)
36+
- `.exception` - Exceptional condition on file descriptor
37+
- `.error` - Error occurred (Linux only)
38+
- `.hangup` - Hangup occurred (Linux only)
39+
40+
## Configuration Flags
41+
42+
- `.edge_trigger` - Edge-triggered notifications (note: behavior differs between Linux and macOS)
43+
- `.one_shot` - Event is disabled after first notification
44+
- `.wake_up` - System wake-up event (Linux only)
45+
- `.exclusive` - Exclusive wake-up (Linux only)
46+
47+
## Platform Differences
48+
49+
### macOS/kqueue vs Linux/epoll
50+
51+
**Event Type Support:**
52+
- macOS kqueue does **not** support: `.peer_hangup`, `.error`, `.hangup`
53+
- Linux epoll supports all event types
54+
55+
**Configuration Flags:**
56+
- macOS kqueue does **not** support: `.wake_up`, `.exclusive`
57+
- Linux epoll supports all configuration flags
58+
59+
**Edge Trigger Behavior:**
60+
- Linux epoll (`EPOLLET`): Triggers once when state changes from unreadable to readable
61+
- macOS kqueue (`EV_CLEAR`): May trigger multiple times even if data is not completely read
62+
63+
When using unsupported features on macOS, the methods will return an error instead of panicking, allowing for graceful degradation.
64+
65+
## Error Handling
66+
67+
All methods that can fail return a `Result` type. Handle errors appropriately:
68+
69+
```v
70+
notifier.add(fd, .read) or {
71+
eprintln('Failed to add fd: ${err}')
72+
return
73+
}
74+
```
75+
76+
On macOS, attempting to use unsupported features will return an error:
77+
78+
```v
79+
// This will fail on macOS with an error message
80+
notifier.add(fd, .hangup) or {
81+
eprintln('Error: ${err}') // "kqueue does not support 'hangup' event type"
82+
}
83+
```
84+
85+
## Thread Safety
86+
87+
Both `EpollNotifier` (Linux) and `KqueueNotifier` (macOS) use fixed-size arrays for event storage, making them thread-safe for concurrent use.

vlib/os/notify/backend_darwin.c.v

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ module notify
33
import time
44
import os
55

6+
// This is the macOS/BSD backend for the notify module using kqueue.
7+
//
8+
// kqueue has different capabilities compared to Linux's epoll:
9+
// - Does not support: peer_hangup, error, hangup event types
10+
// - Does not support: wake_up, exclusive config flags
11+
// - Edge triggering (EV_CLEAR) behaves differently than epoll's EPOLLET
12+
//
13+
// When unsupported features are requested, functions return errors
14+
// instead of panicking to allow graceful degradation.
15+
616
#insert "@VEXEROOT/vlib/os/notify/kqueue.h"
717

818
pub struct C.kevent {

vlib/os/notify/backend_linux.c.v

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ module notify
33
import time
44
import os
55

6+
// This is the Linux backend for the notify module using epoll.
7+
//
8+
// epoll supports all event types and config flags defined in the
9+
// FdNotifier interface, making it the most feature-complete backend.
10+
611
#include <sys/epoll.h>
712

813
pub struct C.epoll_event {

vlib/os/notify/notify_test.c.v

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ fn make_pipe() !(int, int) {
1515
return -1, -1
1616
}
1717

18+
// test_level_trigger tests level-triggered mode where events continue
19+
// to be reported as long as the condition persists (e.g., data available to read)
1820
fn test_level_trigger() {
1921
// currently only linux and macos are supported
2022
$if linux || macos {
@@ -36,6 +38,8 @@ fn test_level_trigger() {
3638
}
3739
}
3840

41+
// test_edge_trigger tests edge-triggered mode where events are only
42+
// reported when the state changes. Note: behavior differs between platforms.
3943
fn test_edge_trigger() {
4044
// currently only linux and macos are supported
4145
$if linux || macos {
@@ -84,6 +88,8 @@ fn test_edge_trigger() {
8488
}
8589
}
8690

91+
// test_one_shot tests one-shot mode where an event is only reported once
92+
// and then must be re-armed to receive further notifications
8793
fn test_one_shot() {
8894
$if linux || macos {
8995
mut notifier := notify.new()!
@@ -109,7 +115,7 @@ fn test_one_shot() {
109115
}
110116
}
111117

112-
// Kqueue does not support 'hangup' event type.
118+
// test_hangup tests hangup event detection (Linux only - kqueue doesn't support it)
113119
fn test_hangup() {
114120
$if linux {
115121
mut notifier := notify.new()!
@@ -132,6 +138,7 @@ fn test_hangup() {
132138
}
133139
}
134140

141+
// test_write tests write readiness notification
135142
fn test_write() {
136143
$if linux || macos {
137144
mut notifier := notify.new()!
@@ -153,6 +160,7 @@ fn test_write() {
153160
}
154161
}
155162

163+
// test_remove tests removing a file descriptor from the watch list
156164
fn test_remove() {
157165
$if linux || macos {
158166
mut notifier := notify.new()!

0 commit comments

Comments
 (0)