cool.io 1.9.4 → 1.10.0
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 +4 -4
- data/.github/workflows/test.yaml +1 -0
- data/.github/workflows/valgrind.yaml +41 -0
- data/Rakefile +7 -19
- data/cool.io.gemspec +1 -3
- data/ext/cool.io/buffer.c +77 -52
- data/ext/cool.io/cool.io.h +6 -0
- data/ext/cool.io/ev_wrap.h +1 -0
- data/ext/cool.io/extconf.rb +0 -1
- data/ext/cool.io/iowatcher.c +18 -1
- data/ext/cool.io/loop.c +21 -19
- data/ext/cool.io/stat_watcher.c +44 -19
- data/ext/cool.io/timer_watcher.c +1 -1
- data/ext/cool.io/watcher.c +13 -1
- data/ext/cool.io/watcher.h +0 -17
- data/ext/libev/ev.c +80 -12
- data/ext/libev/ev_select.c +10 -0
- data/ext/libev/ev_vars.h +4 -0
- data/ext/libev/ev_win32_stat.c +851 -0
- data/ext/libev/ev_wrap.h +4 -0
- data/gems.rb +4 -0
- data/lib/cool.io/dns_resolver.rb +53 -8
- data/lib/cool.io/loop.rb +5 -1
- data/lib/cool.io/version.rb +2 -2
- data/libev_win_select.diff +25 -9
- data/spec/async_watcher_spec.rb +3 -1
- data/spec/detach_race_condition_spec.rb +59 -25
- data/spec/dns_spec.rb +197 -0
- data/spec/fixtures/windows_stat_native.c +1305 -0
- data/spec/iobuffer_spec.rb +88 -1
- data/spec/loop_spec.rb +31 -0
- data/spec/stat_watcher_spec.rb +86 -1
- data/spec/tcp_server_spec.rb +34 -10
- data/spec/watcher_reattach_spec.rb +54 -0
- data/spec/windows_stat_native_spec.rb +193 -0
- data/spec/windows_stat_watcher_spec.rb +363 -0
- metadata +14 -2
data/ext/cool.io/stat_watcher.c
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
#include "ruby.h"
|
|
8
|
+
#ifdef _WIN32
|
|
9
|
+
#include "ruby/encoding.h"
|
|
10
|
+
#endif
|
|
8
11
|
#include "ev_wrap.h"
|
|
9
12
|
|
|
10
13
|
#include "cool.io.h"
|
|
@@ -74,12 +77,16 @@ void Init_coolio_stat_watcher()
|
|
|
74
77
|
* specified how often in seconds the path should be polled for changes.
|
|
75
78
|
* Setting interval to zero uses an "automatic" value (typically around 5
|
|
76
79
|
* seconds) which optimizes performance. Otherwise, values less than
|
|
77
|
-
* 0.1 are not particularly meaningful. Where available (
|
|
78
|
-
* high performance file monitoring interfaces
|
|
80
|
+
* 0.1 are not particularly meaningful. Where available (on Linux and Windows),
|
|
81
|
+
* high performance file monitoring interfaces are used. On Windows, polling
|
|
82
|
+
* remains necessary because notification timing is not guaranteed. An attached
|
|
83
|
+
* Windows watcher may also prevent renaming an ancestor directory until detached.
|
|
79
84
|
*/
|
|
80
85
|
static VALUE Coolio_StatWatcher_initialize(int argc, VALUE *argv, VALUE self)
|
|
81
86
|
{
|
|
82
|
-
|
|
87
|
+
VALUE path, interval;
|
|
88
|
+
const char *path_str;
|
|
89
|
+
long path_len;
|
|
83
90
|
struct Coolio_Watcher *watcher_data;
|
|
84
91
|
|
|
85
92
|
rb_scan_args(argc, argv, "11", &path, &interval);
|
|
@@ -89,13 +96,29 @@ static VALUE Coolio_StatWatcher_initialize(int argc, VALUE *argv, VALUE self)
|
|
|
89
96
|
path = rb_String(path);
|
|
90
97
|
rb_iv_set(self, "@path", path);
|
|
91
98
|
|
|
99
|
+
#ifdef _WIN32
|
|
100
|
+
/* libev's wide Windows APIs and stat wrapper use UTF-8 paths. */
|
|
101
|
+
path = rb_str_export_to_enc(path, rb_utf8_encoding());
|
|
102
|
+
#endif
|
|
103
|
+
path_str = StringValueCStr(path);
|
|
104
|
+
|
|
92
105
|
watcher_data = Coolio_Watcher_ptr(self);
|
|
93
106
|
|
|
107
|
+
/* libev keeps the path pointer passed to ev_stat_init() for the lifetime of
|
|
108
|
+
* the watcher. RSTRING_PTR(path) points into a Ruby String whose buffer
|
|
109
|
+
* GC.compact may relocate, leaving libev with a dangling pointer. Keep an
|
|
110
|
+
* owned copy instead; it is released in Coolio_Watcher_free(). */
|
|
111
|
+
path_len = strlen(path_str);
|
|
112
|
+
if(watcher_data->stat_path)
|
|
113
|
+
xfree(watcher_data->stat_path);
|
|
114
|
+
watcher_data->stat_path = xmalloc(path_len + 1);
|
|
115
|
+
memcpy(watcher_data->stat_path, path_str, path_len + 1);
|
|
116
|
+
|
|
94
117
|
watcher_data->dispatch_callback = Coolio_StatWatcher_dispatch_callback;
|
|
95
118
|
ev_stat_init(
|
|
96
119
|
&watcher_data->event_types.ev_stat,
|
|
97
120
|
Coolio_StatWatcher_libev_callback,
|
|
98
|
-
|
|
121
|
+
watcher_data->stat_path,
|
|
99
122
|
interval == Qnil ? 0 : NUM2DBL(interval)
|
|
100
123
|
);
|
|
101
124
|
watcher_data->event_types.ev_stat.data = (void *)self;
|
|
@@ -123,7 +146,7 @@ static VALUE Coolio_StatWatcher_attach(VALUE self, VALUE loop)
|
|
|
123
146
|
watcher_data = Coolio_Watcher_ptr(self);
|
|
124
147
|
|
|
125
148
|
if(watcher_data->loop != Qnil)
|
|
126
|
-
|
|
149
|
+
rb_funcall(self, rb_intern("detach"), 0);
|
|
127
150
|
|
|
128
151
|
watcher_data->loop = loop;
|
|
129
152
|
|
|
@@ -235,20 +258,22 @@ static VALUE Coolio_StatInfo_build(ev_statdata *statdata_struct)
|
|
|
235
258
|
VALUE blksize = Qnil;
|
|
236
259
|
VALUE blocks = Qnil;
|
|
237
260
|
|
|
238
|
-
mtime = rb_funcall(cTime, at_method, 1,
|
|
239
|
-
ctime = rb_funcall(cTime, at_method, 1,
|
|
240
|
-
atime = rb_funcall(cTime, at_method, 1,
|
|
241
|
-
dev =
|
|
242
|
-
ino =
|
|
243
|
-
mode =
|
|
244
|
-
nlink =
|
|
245
|
-
uid =
|
|
246
|
-
gid =
|
|
247
|
-
rdev =
|
|
248
|
-
size =
|
|
249
|
-
#ifdef
|
|
250
|
-
blksize =
|
|
251
|
-
|
|
261
|
+
mtime = rb_funcall(cTime, at_method, 1, LL2NUM((long long)statdata_struct->st_mtime));
|
|
262
|
+
ctime = rb_funcall(cTime, at_method, 1, LL2NUM((long long)statdata_struct->st_ctime));
|
|
263
|
+
atime = rb_funcall(cTime, at_method, 1, LL2NUM((long long)statdata_struct->st_atime));
|
|
264
|
+
dev = LL2NUM((long long)statdata_struct->st_dev);
|
|
265
|
+
ino = ULL2NUM((unsigned long long)statdata_struct->st_ino);
|
|
266
|
+
mode = LL2NUM((long long)statdata_struct->st_mode);
|
|
267
|
+
nlink = LL2NUM((long long)statdata_struct->st_nlink);
|
|
268
|
+
uid = LL2NUM((long long)statdata_struct->st_uid);
|
|
269
|
+
gid = LL2NUM((long long)statdata_struct->st_gid);
|
|
270
|
+
rdev = LL2NUM((long long)statdata_struct->st_rdev);
|
|
271
|
+
size = LL2NUM((long long)statdata_struct->st_size);
|
|
272
|
+
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
|
273
|
+
blksize = LL2NUM((long long)statdata_struct->st_blksize);
|
|
274
|
+
#endif
|
|
275
|
+
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
|
276
|
+
blocks = LL2NUM((long long)statdata_struct->st_blocks);
|
|
252
277
|
#endif
|
|
253
278
|
|
|
254
279
|
return rb_struct_new(cCoolio_StatInfo,
|
data/ext/cool.io/timer_watcher.c
CHANGED
|
@@ -102,7 +102,7 @@ static VALUE Coolio_TimerWatcher_attach(VALUE self, VALUE loop)
|
|
|
102
102
|
watcher_data = Coolio_Watcher_ptr(self);
|
|
103
103
|
|
|
104
104
|
if(watcher_data->loop != Qnil)
|
|
105
|
-
|
|
105
|
+
rb_funcall(self, rb_intern("detach"), 0);
|
|
106
106
|
|
|
107
107
|
watcher_data->loop = loop;
|
|
108
108
|
|
data/ext/cool.io/watcher.c
CHANGED
|
@@ -14,6 +14,7 @@ static VALUE cCoolio_Watcher = Qnil;
|
|
|
14
14
|
|
|
15
15
|
static VALUE Coolio_Watcher_allocate(VALUE klass);
|
|
16
16
|
static void Coolio_Watcher_mark(void *data);
|
|
17
|
+
static void Coolio_Watcher_free(void *data);
|
|
17
18
|
|
|
18
19
|
static VALUE Coolio_Watcher_initialize(VALUE self);
|
|
19
20
|
static VALUE Coolio_Watcher_attach(VALUE self, VALUE loop);
|
|
@@ -56,7 +57,7 @@ static const rb_data_type_t Coolio_Watcher_type = {
|
|
|
56
57
|
"Coolio::Watcher",
|
|
57
58
|
{
|
|
58
59
|
Coolio_Watcher_mark,
|
|
59
|
-
|
|
60
|
+
Coolio_Watcher_free,
|
|
60
61
|
},
|
|
61
62
|
};
|
|
62
63
|
|
|
@@ -75,6 +76,7 @@ static VALUE Coolio_Watcher_allocate(VALUE klass)
|
|
|
75
76
|
|
|
76
77
|
watcher_data->loop = Qnil;
|
|
77
78
|
watcher_data->enabled = 0;
|
|
79
|
+
watcher_data->stat_path = NULL;
|
|
78
80
|
|
|
79
81
|
return watcher;
|
|
80
82
|
}
|
|
@@ -87,6 +89,16 @@ static void Coolio_Watcher_mark(void *data)
|
|
|
87
89
|
rb_gc_mark(watcher_data->loop);
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
static void Coolio_Watcher_free(void *data)
|
|
93
|
+
{
|
|
94
|
+
struct Coolio_Watcher *watcher_data = data;
|
|
95
|
+
|
|
96
|
+
if(watcher_data->stat_path)
|
|
97
|
+
xfree(watcher_data->stat_path);
|
|
98
|
+
|
|
99
|
+
xfree(watcher_data);
|
|
100
|
+
}
|
|
101
|
+
|
|
90
102
|
static VALUE Coolio_Watcher_initialize(VALUE self)
|
|
91
103
|
{
|
|
92
104
|
rb_raise(rb_eRuntimeError, "watcher base class should not be initialized directly");
|
data/ext/cool.io/watcher.h
CHANGED
|
@@ -7,23 +7,6 @@
|
|
|
7
7
|
#ifndef WATCHER_H
|
|
8
8
|
#define WATCHER_H
|
|
9
9
|
|
|
10
|
-
#define Watcher_Attach(watcher_type, detach_func, watcher, loop) \
|
|
11
|
-
struct Coolio_Watcher *watcher_data; \
|
|
12
|
-
struct Coolio_Loop *loop_data; \
|
|
13
|
-
\
|
|
14
|
-
if(!rb_obj_is_kind_of(loop, cCoolio_Loop)) \
|
|
15
|
-
rb_raise(rb_eArgError, "expected loop to be an instance of Coolio::Loop, not %s", RSTRING_PTR(rb_inspect(loop))); \
|
|
16
|
-
\
|
|
17
|
-
watcher_data = Coolio_Watcher_ptr(watcher); \
|
|
18
|
-
loop_data = Coolio_Loop_ptr(loop); \
|
|
19
|
-
\
|
|
20
|
-
if(watcher_data->loop != Qnil) \
|
|
21
|
-
detach_func(watcher); \
|
|
22
|
-
\
|
|
23
|
-
watcher_data->loop = loop; \
|
|
24
|
-
ev_##watcher_type##_start(loop_data->ev_loop, &watcher_data->event_types.ev_##watcher_type); \
|
|
25
|
-
rb_call_super(1, &loop)
|
|
26
|
-
|
|
27
10
|
#define Watcher_Detach(watcher_type, watcher) \
|
|
28
11
|
struct Coolio_Watcher *watcher_data; \
|
|
29
12
|
\
|
data/ext/libev/ev.c
CHANGED
|
@@ -210,9 +210,20 @@
|
|
|
210
210
|
#else
|
|
211
211
|
# include <io.h>
|
|
212
212
|
# define WIN32_LEAN_AND_MEAN
|
|
213
|
-
|
|
213
|
+
/* ruby.h above already pulled in winsock2.h, so fd_set may be dimensioned
|
|
214
|
+
* already. Defining FD_SETSIZE unconditionally here would only move the bound
|
|
215
|
+
* used by EV_WIN_FD_SET, not the array it indexes. Take whatever is in effect
|
|
216
|
+
* and only supply a default when nothing has been decided yet. */
|
|
217
|
+
# ifndef FD_SETSIZE
|
|
218
|
+
# define FD_SETSIZE 1024
|
|
219
|
+
# endif
|
|
214
220
|
# include <winsock2.h>
|
|
215
221
|
# include <windows.h>
|
|
222
|
+
# include <process.h>
|
|
223
|
+
# ifndef EV_WIN32_STAT_CODEPAGE
|
|
224
|
+
/* Interpret narrow paths using the active Windows code page unless overridden. */
|
|
225
|
+
# define EV_WIN32_STAT_CODEPAGE CP_ACP
|
|
226
|
+
# endif
|
|
216
227
|
# ifndef EV_SELECT_IS_WINSOCKET
|
|
217
228
|
# define EV_SELECT_IS_WINSOCKET 1
|
|
218
229
|
# endif
|
|
@@ -1849,6 +1860,10 @@ typedef struct
|
|
|
1849
1860
|
|
|
1850
1861
|
#endif
|
|
1851
1862
|
|
|
1863
|
+
#if defined(_WIN32) && EV_STAT_ENABLE && EV_ASYNC_ENABLE
|
|
1864
|
+
static void win32_fs_destroy (EV_P);
|
|
1865
|
+
#endif
|
|
1866
|
+
|
|
1852
1867
|
#if EV_FEATURE_API
|
|
1853
1868
|
# define EV_RELEASE_CB if (expect_false (release_cb)) release_cb (EV_A)
|
|
1854
1869
|
# define EV_ACQUIRE_CB if (expect_false (acquire_cb)) acquire_cb (EV_A)
|
|
@@ -2400,8 +2415,8 @@ static ANSIG signals [EV_NSIG - 1];
|
|
|
2400
2415
|
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
|
|
2401
2416
|
|
|
2402
2417
|
noinline ecb_cold
|
|
2403
|
-
static
|
|
2404
|
-
|
|
2418
|
+
static int
|
|
2419
|
+
evpipe_init_try (EV_P)
|
|
2405
2420
|
{
|
|
2406
2421
|
if (!ev_is_active (&pipe_w))
|
|
2407
2422
|
{
|
|
@@ -2416,8 +2431,8 @@ evpipe_init (EV_P)
|
|
|
2416
2431
|
if (fds [1] < 0)
|
|
2417
2432
|
# endif
|
|
2418
2433
|
{
|
|
2419
|
-
|
|
2420
|
-
|
|
2434
|
+
if (pipe (fds))
|
|
2435
|
+
return 0;
|
|
2421
2436
|
|
|
2422
2437
|
fd_intern (fds [0]);
|
|
2423
2438
|
}
|
|
@@ -2443,6 +2458,16 @@ evpipe_init (EV_P)
|
|
|
2443
2458
|
ev_io_start (EV_A_ &pipe_w);
|
|
2444
2459
|
ev_unref (EV_A); /* watcher should not keep loop alive */
|
|
2445
2460
|
}
|
|
2461
|
+
|
|
2462
|
+
return 1;
|
|
2463
|
+
}
|
|
2464
|
+
|
|
2465
|
+
noinline ecb_cold
|
|
2466
|
+
static void
|
|
2467
|
+
evpipe_init (EV_P)
|
|
2468
|
+
{
|
|
2469
|
+
while (!evpipe_init_try (EV_A))
|
|
2470
|
+
ev_syserr ("(libev) error creating signal/async pipe");
|
|
2446
2471
|
}
|
|
2447
2472
|
|
|
2448
2473
|
inline_speed void
|
|
@@ -2908,6 +2933,10 @@ loop_init (EV_P_ unsigned int flags) EV_THROW
|
|
|
2908
2933
|
pipe_write_wanted = 0;
|
|
2909
2934
|
evpipe [0] = -1;
|
|
2910
2935
|
evpipe [1] = -1;
|
|
2936
|
+
#if defined(_WIN32) && EV_STAT_ENABLE && EV_ASYNC_ENABLE
|
|
2937
|
+
win32_fs = 0;
|
|
2938
|
+
win32_fs_disabled = (flags & EVFLAG_NOINOTIFY) != 0;
|
|
2939
|
+
#endif
|
|
2911
2940
|
#if EV_USE_INOTIFY
|
|
2912
2941
|
fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
|
|
2913
2942
|
#endif
|
|
@@ -2976,6 +3005,10 @@ ev_loop_destroy (EV_P)
|
|
|
2976
3005
|
}
|
|
2977
3006
|
#endif
|
|
2978
3007
|
|
|
3008
|
+
#if defined(_WIN32) && EV_STAT_ENABLE && EV_ASYNC_ENABLE
|
|
3009
|
+
win32_fs_destroy (EV_A);
|
|
3010
|
+
#endif
|
|
3011
|
+
|
|
2979
3012
|
if (ev_is_active (&pipe_w))
|
|
2980
3013
|
{
|
|
2981
3014
|
/*ev_ref (EV_A);*/
|
|
@@ -4324,17 +4357,16 @@ ev_child_stop (EV_P_ ev_child *w) EV_THROW
|
|
|
4324
4357
|
|
|
4325
4358
|
#if EV_STAT_ENABLE
|
|
4326
4359
|
|
|
4327
|
-
# ifdef _WIN32
|
|
4328
|
-
# undef lstat
|
|
4329
|
-
# define lstat(a,b) _stati64 (a,b)
|
|
4330
|
-
# endif
|
|
4331
|
-
|
|
4332
4360
|
#define DEF_STAT_INTERVAL 5.0074891
|
|
4333
4361
|
#define NFS_STAT_INTERVAL 30.1074891 /* for filesystems potentially failing inotify */
|
|
4334
4362
|
#define MIN_STAT_INTERVAL 0.1074891
|
|
4335
4363
|
|
|
4336
4364
|
noinline static void stat_timer_cb (EV_P_ ev_timer *w_, int revents);
|
|
4337
4365
|
|
|
4366
|
+
#if defined(_WIN32) && EV_ASYNC_ENABLE
|
|
4367
|
+
# include "ev_win32_stat.c"
|
|
4368
|
+
#endif
|
|
4369
|
+
|
|
4338
4370
|
#if EV_USE_INOTIFY
|
|
4339
4371
|
|
|
4340
4372
|
/* the * 2 is to allow for alignment padding, which for some reason is >> 8 */
|
|
@@ -4575,7 +4607,23 @@ infy_fork (EV_P)
|
|
|
4575
4607
|
#endif
|
|
4576
4608
|
|
|
4577
4609
|
#ifdef _WIN32
|
|
4578
|
-
|
|
4610
|
+
static int
|
|
4611
|
+
win32_stat (const char *path, ev_statdata *attr)
|
|
4612
|
+
{
|
|
4613
|
+
int result;
|
|
4614
|
+
int length = MultiByteToWideChar (EV_WIN32_STAT_CODEPAGE, 0, path, -1, 0, 0);
|
|
4615
|
+
wchar_t *wide;
|
|
4616
|
+
if (!length)
|
|
4617
|
+
{ errno = EINVAL; return -1; }
|
|
4618
|
+
wide = (wchar_t *)malloc (length * sizeof (wchar_t));
|
|
4619
|
+
if (!wide)
|
|
4620
|
+
{ errno = ENOMEM; return -1; }
|
|
4621
|
+
MultiByteToWideChar (EV_WIN32_STAT_CODEPAGE, 0, path, -1, wide, length);
|
|
4622
|
+
result = _wstati64 (wide, attr);
|
|
4623
|
+
free (wide);
|
|
4624
|
+
return result;
|
|
4625
|
+
}
|
|
4626
|
+
# define EV_LSTAT(p,b) win32_stat (p, b)
|
|
4579
4627
|
#else
|
|
4580
4628
|
# define EV_LSTAT(p,b) lstat (p, b)
|
|
4581
4629
|
#endif
|
|
@@ -4583,7 +4631,7 @@ infy_fork (EV_P)
|
|
|
4583
4631
|
void
|
|
4584
4632
|
ev_stat_stat (EV_P_ ev_stat *w) EV_THROW
|
|
4585
4633
|
{
|
|
4586
|
-
if (
|
|
4634
|
+
if (EV_LSTAT (w->path, &w->attr) < 0)
|
|
4587
4635
|
w->attr.st_nlink = 0;
|
|
4588
4636
|
else if (!w->attr.st_nlink)
|
|
4589
4637
|
w->attr.st_nlink = 1;
|
|
@@ -4595,6 +4643,11 @@ stat_timer_cb (EV_P_ ev_timer *w_, int revents)
|
|
|
4595
4643
|
{
|
|
4596
4644
|
ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer));
|
|
4597
4645
|
|
|
4646
|
+
#if defined(_WIN32) && EV_ASYNC_ENABLE
|
|
4647
|
+
if (revents & EV_TIMER)
|
|
4648
|
+
win32_fs_add (EV_A_ w, 1); /* retry missing parents or failed directory handles */
|
|
4649
|
+
#endif
|
|
4650
|
+
|
|
4598
4651
|
ev_statdata prev = w->attr;
|
|
4599
4652
|
ev_stat_stat (EV_A_ w);
|
|
4600
4653
|
|
|
@@ -4617,6 +4670,12 @@ stat_timer_cb (EV_P_ ev_timer *w_, int revents)
|
|
|
4617
4670
|
/* to ensure that prev is always different to attr */
|
|
4618
4671
|
w->prev = prev;
|
|
4619
4672
|
|
|
4673
|
+
#if defined(_WIN32) && EV_ASYNC_ENABLE
|
|
4674
|
+
if (!prev.st_nlink || !w->attr.st_nlink
|
|
4675
|
+
|| (prev.st_mode & S_IFMT) != (w->attr.st_mode & S_IFMT))
|
|
4676
|
+
win32_fs_add (EV_A_ w, 0); /* register directory children after creation */
|
|
4677
|
+
#endif
|
|
4678
|
+
|
|
4620
4679
|
#if EV_USE_INOTIFY
|
|
4621
4680
|
if (fs_fd >= 0)
|
|
4622
4681
|
{
|
|
@@ -4658,6 +4717,11 @@ ev_stat_start (EV_P_ ev_stat *w) EV_THROW
|
|
|
4658
4717
|
|
|
4659
4718
|
ev_start (EV_A_ (W)w, 1);
|
|
4660
4719
|
|
|
4720
|
+
#if defined(_WIN32) && EV_ASYNC_ENABLE
|
|
4721
|
+
win32_fs_add (EV_A_ w, 0);
|
|
4722
|
+
stat_timer_cb (EV_A_ &w->timer, 0); /* close the stat/registration race */
|
|
4723
|
+
#endif
|
|
4724
|
+
|
|
4661
4725
|
EV_FREQUENT_CHECK;
|
|
4662
4726
|
}
|
|
4663
4727
|
|
|
@@ -4670,6 +4734,10 @@ ev_stat_stop (EV_P_ ev_stat *w) EV_THROW
|
|
|
4670
4734
|
|
|
4671
4735
|
EV_FREQUENT_CHECK;
|
|
4672
4736
|
|
|
4737
|
+
#if defined(_WIN32) && EV_ASYNC_ENABLE
|
|
4738
|
+
win32_fs_del (EV_A_ w);
|
|
4739
|
+
#endif
|
|
4740
|
+
|
|
4673
4741
|
#if EV_USE_INOTIFY
|
|
4674
4742
|
infy_del (EV_A_ w);
|
|
4675
4743
|
#endif
|
data/ext/libev/ev_select.c
CHANGED
|
@@ -107,6 +107,16 @@ if (__i == ((fd_set *)(set))->fd_count) {\
|
|
|
107
107
|
#define EV_WIN_FD_ZERO(set) (((fd_set *)(set))->fd_count=0)
|
|
108
108
|
#define EV_WIN_FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)(fd), (fd_set *)(set))
|
|
109
109
|
#define EV_WIN_FD_COUNT(set) (((fd_set *)(set))->fd_count)
|
|
110
|
+
|
|
111
|
+
/*
|
|
112
|
+
fd_set is dimensioned by whatever FD_SETSIZE was in effect when winsock2.h was
|
|
113
|
+
first pulled in, but EV_WIN_FD_SET and select_modify bound-check against the
|
|
114
|
+
FD_SETSIZE visible here. The two are decided by separate paths, so if the bound
|
|
115
|
+
ever exceeds the declared array we would write past the end of the allocation in
|
|
116
|
+
select_init. Catch that at build time instead.
|
|
117
|
+
*/
|
|
118
|
+
typedef char coolio_fd_setsize_matches_fd_set[
|
|
119
|
+
(sizeof (((fd_set *)0)->fd_array) / sizeof (SOCKET) >= (size_t)FD_SETSIZE) ? 1 : -1];
|
|
110
120
|
/* ######################################## */
|
|
111
121
|
#else
|
|
112
122
|
#define EV_WIN_FD_CLR FD_CLR
|
data/ext/libev/ev_vars.h
CHANGED
|
@@ -181,6 +181,10 @@ VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE])
|
|
|
181
181
|
#endif
|
|
182
182
|
|
|
183
183
|
VARx(EV_ATOMIC_T, sig_pending)
|
|
184
|
+
#if defined(_WIN32) && EV_STAT_ENABLE && EV_ASYNC_ENABLE
|
|
185
|
+
VARx(struct ev_win32_fs *, win32_fs)
|
|
186
|
+
VARx(int, win32_fs_disabled)
|
|
187
|
+
#endif
|
|
184
188
|
#if EV_USE_SIGNALFD || EV_GENWRAP
|
|
185
189
|
VARx(int, sigfd)
|
|
186
190
|
VARx(ev_io, sigfd_w)
|