io-watch 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/ext/io/watch/inotify.c +99 -6
- data/lib/io/watch/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d6ca67070f5fe227f2e06b5c5fa8bc2498a640aa88fb7e21a21da0bf5a09434
|
4
|
+
data.tar.gz: 8973b98b3412da62ddcca9850ab04c3c69b1e00ab15e35e2bddf275a99f20823
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db38f21e23045fb052299ee4974ee4cecd283ea406f32dd5a5e453ef7125c8d0a9086589ed6d0b8c0977311071367b2ba2429f93f71127f7e335b8f451208de4
|
7
|
+
data.tar.gz: c6c6af9a7975ea6912b582bddc8b52ac0ef480de0a30c83d70c1781036e46eb93d97b87c58b0e12a558d29bff57955c8a75db483d97b427775b2da13ad557481
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/ext/io/watch/inotify.c
CHANGED
@@ -9,6 +9,8 @@
|
|
9
9
|
#include <dirent.h>
|
10
10
|
#include <string.h>
|
11
11
|
#include <sys/stat.h>
|
12
|
+
#include <time.h>
|
13
|
+
#include <poll.h>
|
12
14
|
|
13
15
|
enum {
|
14
16
|
DEBUG = 0,
|
@@ -18,11 +20,16 @@ struct IO_Watch_Watch {
|
|
18
20
|
int watch_descriptor;
|
19
21
|
char *path;
|
20
22
|
int index;
|
23
|
+
|
24
|
+
int modified;
|
21
25
|
};
|
22
26
|
|
23
27
|
struct IO_Watch_Watch_Array {
|
24
28
|
size_t size;
|
25
29
|
size_t capacity;
|
30
|
+
|
31
|
+
size_t pending;
|
32
|
+
|
26
33
|
struct IO_Watch_Watch *watches;
|
27
34
|
};
|
28
35
|
|
@@ -31,6 +38,7 @@ struct IO_Watch_Watch_Array {
|
|
31
38
|
void IO_Watch_Watch_Array_initialize(struct IO_Watch_Watch_Array *array) {
|
32
39
|
array->size = 0;
|
33
40
|
array->capacity = 16;
|
41
|
+
array->pending = 0;
|
34
42
|
array->watches = malloc(array->capacity * sizeof(struct IO_Watch_Watch));
|
35
43
|
if (!array->watches) {
|
36
44
|
perror("io-watch:IO_Watch_Watch_Array_initialize:malloc");
|
@@ -176,6 +184,46 @@ void IO_Watch_INotify_print_event(struct inotify_event *event) {
|
|
176
184
|
fprintf(stderr, "\n");
|
177
185
|
}
|
178
186
|
|
187
|
+
static size_t IO_Watch_INotify_flush_events(struct IO_Watch_Watch_Array watch_array) {
|
188
|
+
size_t count = 0;
|
189
|
+
|
190
|
+
if (watch_array.pending == 0) {
|
191
|
+
return 0;
|
192
|
+
}
|
193
|
+
|
194
|
+
for (size_t i = 0; i < watch_array.size; i++) {
|
195
|
+
int modified = watch_array.watches[i].modified;
|
196
|
+
if (modified) {
|
197
|
+
count++;
|
198
|
+
|
199
|
+
printf("{\"index\":%d,\"mask\":%u}\n", watch_array.watches[i].index, modified);
|
200
|
+
watch_array.watches[i].modified = 0;
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
watch_array.pending = 0;
|
205
|
+
|
206
|
+
fflush(stdout);
|
207
|
+
|
208
|
+
if (DEBUG) fprintf(stderr, "io-watch:IO_Watch_INotify_flush_events: Flushed %zu events\n", count);
|
209
|
+
|
210
|
+
return count;
|
211
|
+
}
|
212
|
+
|
213
|
+
static float IO_Watch_handle_timeout(float latency, struct timespec *start_time) {
|
214
|
+
if (start_time) {
|
215
|
+
struct timespec current_time;
|
216
|
+
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
217
|
+
|
218
|
+
float delta = current_time.tv_sec - start_time->tv_sec;
|
219
|
+
delta += (current_time.tv_nsec - start_time->tv_nsec) / 1e9;
|
220
|
+
|
221
|
+
return latency - delta;
|
222
|
+
} else {
|
223
|
+
return 0.0;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
179
227
|
void IO_Watch_run(struct IO_Watch *watch) {
|
180
228
|
int fd = inotify_init1(IN_NONBLOCK);
|
181
229
|
if (fd == -1) {
|
@@ -193,16 +241,60 @@ void IO_Watch_run(struct IO_Watch *watch) {
|
|
193
241
|
IO_Watch_Watch_Array_scan(fd, &watch_array, path, i);
|
194
242
|
}
|
195
243
|
|
244
|
+
float latency = watch->latency;
|
245
|
+
|
246
|
+
// If start_time is non-null, it means we are now coallescing events, up to the specified latency:
|
247
|
+
struct timespec start_time_buffer, *start_time = NULL;
|
248
|
+
|
196
249
|
printf("{\"status\":\"started\"}\n");
|
197
250
|
fflush(stdout);
|
198
251
|
|
199
252
|
char buffer[BUFFER_SIZE] __attribute__ ((aligned(8)));
|
200
253
|
|
201
254
|
while (1) {
|
255
|
+
// Check for any events:
|
202
256
|
ssize_t result = read(fd, buffer, BUFFER_SIZE);
|
203
|
-
|
204
|
-
|
205
|
-
|
257
|
+
|
258
|
+
// Calculate the timeout, if any:
|
259
|
+
float timeout = IO_Watch_handle_timeout(latency, start_time);
|
260
|
+
|
261
|
+
// We need to check if the timeout has expired:
|
262
|
+
if (timeout < 0.0) {
|
263
|
+
if (DEBUG) fprintf(stderr, "io-watch:IO_Watch_run: Timeout expired\n");
|
264
|
+
|
265
|
+
start_time = NULL;
|
266
|
+
// Flush any pending events:
|
267
|
+
IO_Watch_INotify_flush_events(watch_array);
|
268
|
+
}
|
269
|
+
|
270
|
+
// If no events are available, we have to wait for the timeout:
|
271
|
+
if (result == -1) {
|
272
|
+
if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
273
|
+
perror("(io-watch:IO_Watch_run:read)");
|
274
|
+
exit(EXIT_FAILURE);
|
275
|
+
}
|
276
|
+
|
277
|
+
if (DEBUG) fprintf(stderr, "io-watch:IO_Watch_run: No events available, waiting for %0.4f seconds\n", timeout);
|
278
|
+
|
279
|
+
// Wait until the file descriptor becomes readable:
|
280
|
+
struct pollfd poll_fd = {fd, POLLIN, 0};
|
281
|
+
int poll_timeout = start_time ? (int) (timeout * 1e3) : -1;
|
282
|
+
|
283
|
+
// If we have a timeout of 0.0, we have to poll for at least 1 ms:
|
284
|
+
if (poll_timeout == 0 && timeout > 0.0) {
|
285
|
+
poll_timeout = 1;
|
286
|
+
}
|
287
|
+
|
288
|
+
if (DEBUG) fprintf(stderr, "io-watch:IO_Watch_run:poll: Polling for %d ms\n", poll_timeout);
|
289
|
+
poll(&poll_fd, 1, poll_timeout);
|
290
|
+
continue;
|
291
|
+
}
|
292
|
+
|
293
|
+
// If we have received events, we have to set the start_time if it is not set:
|
294
|
+
if (!start_time) {
|
295
|
+
if (DEBUG) fprintf(stderr, "io-watch:IO_Watch_run: Setting start_time\n");
|
296
|
+
start_time = &start_time_buffer;
|
297
|
+
clock_gettime(CLOCK_MONOTONIC, start_time);
|
206
298
|
}
|
207
299
|
|
208
300
|
for (ssize_t offset = 0; offset < result;) {
|
@@ -225,7 +317,9 @@ void IO_Watch_run(struct IO_Watch *watch) {
|
|
225
317
|
ssize_t index = IO_Watch_Watch_Array_find(&watch_array, event->wd);
|
226
318
|
|
227
319
|
if (index != -1) {
|
228
|
-
|
320
|
+
if (DEBUG) fprintf(stderr, "io-watch:IO_Watch_run: Modified path %s mask=%d\n", watch_array.watches[index].path, event->mask);
|
321
|
+
watch_array.watches[index].modified |= event->mask;
|
322
|
+
watch_array.pending += 1;
|
229
323
|
|
230
324
|
// If a new directory is created, add a watch for it
|
231
325
|
if (event->mask & IN_CREATE && event->mask & IN_ISDIR) {
|
@@ -239,9 +333,8 @@ void IO_Watch_run(struct IO_Watch *watch) {
|
|
239
333
|
|
240
334
|
offset += sizeof(struct inotify_event) + event->len;
|
241
335
|
}
|
242
|
-
fflush(stdout);
|
243
336
|
}
|
244
|
-
|
337
|
+
|
245
338
|
for (size_t i = 0; i < watch_array.size; i++) {
|
246
339
|
inotify_rm_watch(fd, watch_array.watches[i].watch_descriptor);
|
247
340
|
free(watch_array.watches[i].path);
|
data/lib/io/watch/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-watch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -37,7 +37,7 @@ cert_chain:
|
|
37
37
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
38
38
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
39
39
|
-----END CERTIFICATE-----
|
40
|
-
date: 2024-08-
|
40
|
+
date: 2024-08-12 00:00:00.000000000 Z
|
41
41
|
dependencies: []
|
42
42
|
description:
|
43
43
|
email:
|
metadata.gz.sig
CHANGED
Binary file
|