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 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