io-watch 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b3d57b500111de6639098f96580da6ddfc5029f77fc0daf97159e54415ea7c5
4
- data.tar.gz: 0ee6cfbdb782214fc141b713f7396448e92ae438244939ed48b9681a6e620f7f
3
+ metadata.gz: 0d6ca67070f5fe227f2e06b5c5fa8bc2498a640aa88fb7e21a21da0bf5a09434
4
+ data.tar.gz: 8973b98b3412da62ddcca9850ab04c3c69b1e00ab15e35e2bddf275a99f20823
5
5
  SHA512:
6
- metadata.gz: 3e4873bbd69789206c2704fe3e20914c7955c79d2310513adcf8dd9371c6773bf9d0a729b19b1de4a18fe852631435184559d98600d7de5b2ecd81a5a633075a
7
- data.tar.gz: cbc9fdaedb8f1383e36e845cd07341e2427e706c205a94da35b355eb87ae049f9d2a256d30beb3a4616f35fbcf10f66e5022e0653849a3762a01376a7937f003
6
+ metadata.gz: db38f21e23045fb052299ee4974ee4cecd283ea406f32dd5a5e453ef7125c8d0a9086589ed6d0b8c0977311071367b2ba2429f93f71127f7e335b8f451208de4
7
+ data.tar.gz: c6c6af9a7975ea6912b582bddc8b52ac0ef480de0a30c83d70c1781036e46eb93d97b87c58b0e12a558d29bff57955c8a75db483d97b427775b2da13ad557481
checksums.yaml.gz.sig CHANGED
Binary file
@@ -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, &current_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
- if (result == -1 && errno != EAGAIN) {
204
- perror("(io-watch:IO_Watch_run:read)");
205
- exit(EXIT_FAILURE);
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
- printf("{\"index\":%d,\"mask\":%u}\n", watch_array.watches[index].index, event->mask);
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);
@@ -5,6 +5,6 @@
5
5
 
6
6
  class IO
7
7
  module Watch
8
- VERSION = '0.6.1'
8
+ VERSION = '0.6.2'
9
9
  end
10
10
  end
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.1
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-11 00:00:00.000000000 Z
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