rev 0.1.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.
@@ -0,0 +1,117 @@
1
+ /*
2
+ * libev win32 compatibility cruft
3
+ *
4
+ * Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are
9
+ * met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ *
14
+ * * Redistributions in binary form must reproduce the above
15
+ * copyright notice, this list of conditions and the following
16
+ * disclaimer in the documentation and/or other materials provided
17
+ * with the distribution.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+
32
+ #ifdef _WIN32
33
+
34
+ #include <sys/timeb.h>
35
+
36
+ /* note: the comment below could not be substantiated, but what would I care */
37
+ /* MSDN says this is required to handle SIGFPE */
38
+ volatile double SIGFPE_REQ = 0.0f;
39
+
40
+ /* oh, the humanity! */
41
+ static int
42
+ ev_pipe (int filedes [2])
43
+ {
44
+ struct sockaddr_in addr = { 0 };
45
+ int addr_size = sizeof (addr);
46
+ SOCKET listener;
47
+ SOCKET sock [2] = { -1, -1 };
48
+
49
+ if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
50
+ return -1;
51
+
52
+ addr.sin_family = AF_INET;
53
+ addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
54
+ addr.sin_port = 0;
55
+
56
+ if (bind (listener, (struct sockaddr *)&addr, addr_size))
57
+ goto fail;
58
+
59
+ if (getsockname(listener, (struct sockaddr *)&addr, &addr_size))
60
+ goto fail;
61
+
62
+ if (listen (listener, 1))
63
+ goto fail;
64
+
65
+ if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
66
+ goto fail;
67
+
68
+ if (connect (sock[0], (struct sockaddr *)&addr, addr_size))
69
+ goto fail;
70
+
71
+ if ((sock[1] = accept (listener, 0, 0)) < 0)
72
+ goto fail;
73
+
74
+ closesocket (listener);
75
+
76
+ #if EV_SELECT_IS_WINSOCKET
77
+ filedes [0] = _open_osfhandle (sock [0], 0);
78
+ filedes [1] = _open_osfhandle (sock [1], 0);
79
+ #else
80
+ /* when select isn't winsocket, we also expect socket, connect, accept etc.
81
+ * to work on fds */
82
+ filedes [0] = sock [0];
83
+ filedes [1] = sock [1];
84
+ #endif
85
+
86
+ return 0;
87
+
88
+ fail:
89
+ closesocket (listener);
90
+
91
+ if (sock [0] != INVALID_SOCKET) closesocket (sock [0]);
92
+ if (sock [1] != INVALID_SOCKET) closesocket (sock [1]);
93
+
94
+ return -1;
95
+ }
96
+
97
+ #undef pipe
98
+ #define pipe(filedes) ev_pipe (filedes)
99
+
100
+ static int
101
+ ev_gettimeofday (struct timeval *tv, struct timezone *tz)
102
+ {
103
+ struct _timeb tb;
104
+
105
+ _ftime (&tb);
106
+
107
+ tv->tv_sec = (long)tb.time;
108
+ tv->tv_usec = ((long)tb.millitm) * 1000;
109
+
110
+ return 0;
111
+ }
112
+
113
+ #undef gettimeofday
114
+ #define gettimeofday(tv,tz) ev_gettimeofday (tv, tz)
115
+
116
+ #endif
117
+
@@ -0,0 +1,132 @@
1
+ /* DO NOT EDIT, automatically generated by update_ev_wrap */
2
+ #ifndef EV_WRAP_H
3
+ #define EV_WRAP_H
4
+ #define now_floor ((loop)->now_floor)
5
+ #define mn_now ((loop)->mn_now)
6
+ #define rtmn_diff ((loop)->rtmn_diff)
7
+ #define io_blocktime ((loop)->io_blocktime)
8
+ #define timeout_blocktime ((loop)->timeout_blocktime)
9
+ #define backend ((loop)->backend)
10
+ #define activecnt ((loop)->activecnt)
11
+ #define loop_count ((loop)->loop_count)
12
+ #define backend_fd ((loop)->backend_fd)
13
+ #define backend_fudge ((loop)->backend_fudge)
14
+ #define backend_modify ((loop)->backend_modify)
15
+ #define backend_poll ((loop)->backend_poll)
16
+ #define curpid ((loop)->curpid)
17
+ #define postfork ((loop)->postfork)
18
+ #define vec_ri ((loop)->vec_ri)
19
+ #define vec_ro ((loop)->vec_ro)
20
+ #define vec_wi ((loop)->vec_wi)
21
+ #define vec_wo ((loop)->vec_wo)
22
+ #define vec_max ((loop)->vec_max)
23
+ #define polls ((loop)->polls)
24
+ #define pollmax ((loop)->pollmax)
25
+ #define pollcnt ((loop)->pollcnt)
26
+ #define pollidxs ((loop)->pollidxs)
27
+ #define pollidxmax ((loop)->pollidxmax)
28
+ #define epoll_events ((loop)->epoll_events)
29
+ #define epoll_eventmax ((loop)->epoll_eventmax)
30
+ #define kqueue_changes ((loop)->kqueue_changes)
31
+ #define kqueue_changemax ((loop)->kqueue_changemax)
32
+ #define kqueue_changecnt ((loop)->kqueue_changecnt)
33
+ #define kqueue_events ((loop)->kqueue_events)
34
+ #define kqueue_eventmax ((loop)->kqueue_eventmax)
35
+ #define port_events ((loop)->port_events)
36
+ #define port_eventmax ((loop)->port_eventmax)
37
+ #define anfds ((loop)->anfds)
38
+ #define anfdmax ((loop)->anfdmax)
39
+ #define pendings ((loop)->pendings)
40
+ #define pendingmax ((loop)->pendingmax)
41
+ #define pendingcnt ((loop)->pendingcnt)
42
+ #define fdchanges ((loop)->fdchanges)
43
+ #define fdchangemax ((loop)->fdchangemax)
44
+ #define fdchangecnt ((loop)->fdchangecnt)
45
+ #define timers ((loop)->timers)
46
+ #define timermax ((loop)->timermax)
47
+ #define timercnt ((loop)->timercnt)
48
+ #define periodics ((loop)->periodics)
49
+ #define periodicmax ((loop)->periodicmax)
50
+ #define periodiccnt ((loop)->periodiccnt)
51
+ #define idles ((loop)->idles)
52
+ #define idlemax ((loop)->idlemax)
53
+ #define idlecnt ((loop)->idlecnt)
54
+ #define idleall ((loop)->idleall)
55
+ #define prepares ((loop)->prepares)
56
+ #define preparemax ((loop)->preparemax)
57
+ #define preparecnt ((loop)->preparecnt)
58
+ #define checks ((loop)->checks)
59
+ #define checkmax ((loop)->checkmax)
60
+ #define checkcnt ((loop)->checkcnt)
61
+ #define forks ((loop)->forks)
62
+ #define forkmax ((loop)->forkmax)
63
+ #define forkcnt ((loop)->forkcnt)
64
+ #define fs_fd ((loop)->fs_fd)
65
+ #define fs_w ((loop)->fs_w)
66
+ #define fs_hash ((loop)->fs_hash)
67
+ #else
68
+ #undef EV_WRAP_H
69
+ #undef now_floor
70
+ #undef mn_now
71
+ #undef rtmn_diff
72
+ #undef io_blocktime
73
+ #undef timeout_blocktime
74
+ #undef backend
75
+ #undef activecnt
76
+ #undef loop_count
77
+ #undef backend_fd
78
+ #undef backend_fudge
79
+ #undef backend_modify
80
+ #undef backend_poll
81
+ #undef curpid
82
+ #undef postfork
83
+ #undef vec_ri
84
+ #undef vec_ro
85
+ #undef vec_wi
86
+ #undef vec_wo
87
+ #undef vec_max
88
+ #undef polls
89
+ #undef pollmax
90
+ #undef pollcnt
91
+ #undef pollidxs
92
+ #undef pollidxmax
93
+ #undef epoll_events
94
+ #undef epoll_eventmax
95
+ #undef kqueue_changes
96
+ #undef kqueue_changemax
97
+ #undef kqueue_changecnt
98
+ #undef kqueue_events
99
+ #undef kqueue_eventmax
100
+ #undef port_events
101
+ #undef port_eventmax
102
+ #undef anfds
103
+ #undef anfdmax
104
+ #undef pendings
105
+ #undef pendingmax
106
+ #undef pendingcnt
107
+ #undef fdchanges
108
+ #undef fdchangemax
109
+ #undef fdchangecnt
110
+ #undef timers
111
+ #undef timermax
112
+ #undef timercnt
113
+ #undef periodics
114
+ #undef periodicmax
115
+ #undef periodiccnt
116
+ #undef idles
117
+ #undef idlemax
118
+ #undef idlecnt
119
+ #undef idleall
120
+ #undef prepares
121
+ #undef preparemax
122
+ #undef preparecnt
123
+ #undef checks
124
+ #undef checkmax
125
+ #undef checkcnt
126
+ #undef forks
127
+ #undef forkmax
128
+ #undef forkcnt
129
+ #undef fs_fd
130
+ #undef fs_w
131
+ #undef fs_hash
132
+ #endif
@@ -0,0 +1,36 @@
1
+ require 'mkmf'
2
+
3
+ flags = []
4
+
5
+ unless have_func('rb_thread_blocking_region') and have_macro('RB_UBF_DFL', 'ruby.h')
6
+ abort "Rev requires (a fairly recent) Ruby 1.9 or greater"
7
+ end
8
+
9
+ if have_header('sys/select.h')
10
+ flags << '-DEV_USE_SELECT'
11
+ end
12
+
13
+ if have_header('poll.h')
14
+ flags << '-DEV_USE_POLL'
15
+ end
16
+
17
+ if have_header('sys/epoll.h')
18
+ flags << '-DEV_USE_EPOLL'
19
+ end
20
+
21
+ if have_header('sys/event.h') and have_header('sys/queue.h')
22
+ flags << '-DEV_USE_KQUEUE'
23
+ end
24
+
25
+ if have_header('port.h')
26
+ flags << '-DEV_USE_PORT'
27
+ end
28
+
29
+ if have_header('sys/inotify.h')
30
+ flags << '-DEV_USE_INOTIFY'
31
+ end
32
+
33
+ $CFLAGS << ' ' << flags.join(' ')
34
+
35
+ dir_config('rev_ext')
36
+ create_makefile('rev_ext')
@@ -0,0 +1,44 @@
1
+ /*
2
+ * Copyright (C) 2007 Tony Arcieri
3
+ * You may redistribute this under the terms of the Ruby license.
4
+ * See LICENSE for details
5
+ */
6
+
7
+ #ifndef REV_H
8
+ #define REV_H
9
+
10
+ #include "ruby.h"
11
+
12
+ struct Rev_Event
13
+ {
14
+ /* These values are used to extract events from libev callbacks */
15
+ VALUE watcher;
16
+ int revents;
17
+ };
18
+
19
+ struct Rev_Loop
20
+ {
21
+ struct ev_loop *ev_loop;
22
+ int default_loop;
23
+
24
+ int events_received;
25
+ int eventbuf_size;
26
+ struct Rev_Event *eventbuf;
27
+ };
28
+
29
+ struct Rev_Watcher
30
+ {
31
+ union {
32
+ struct ev_io ev_io;
33
+ struct ev_timer ev_timer;
34
+ } event_types;
35
+
36
+ int enabled;
37
+ VALUE loop;
38
+
39
+ void (*dispatch_callback)(VALUE self, int revents);
40
+ };
41
+
42
+ void Rev_Loop_process_event(VALUE watcher, int revents);
43
+
44
+ #endif
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Copyright (C) 2007 Tony Arcieri
3
+ * You may redistribute this under the terms of the Ruby license.
4
+ * See LICENSE for details
5
+ */
6
+
7
+ #include "ruby.h"
8
+
9
+ #define EV_STANDALONE 1
10
+ #include "../libev/ev.c"
11
+
12
+ #include "rev.h"
13
+
14
+ static VALUE mRev = Qnil;
15
+
16
+ void Init_rev_ext()
17
+ {
18
+ ev_set_allocator((void *(*)(void *, long))xrealloc);
19
+ mRev = rb_define_module("Rev");
20
+
21
+ /* Make libev version available in Ruby */
22
+ rb_define_const(mRev, "LIBEV_VERSION", rb_sprintf("%d.%d", ev_version_major(), ev_version_minor()));
23
+
24
+ /* Initializers for other modules */
25
+ Init_rev_loop();
26
+ Init_rev_watcher();
27
+ Init_rev_io_watcher();
28
+ Init_rev_timer_watcher();
29
+ }
@@ -0,0 +1,157 @@
1
+ /*
2
+ * Copyright (C) 2007 Tony Arcieri
3
+ * You may redistribute this under the terms of the Ruby license.
4
+ * See LICENSE for details
5
+ */
6
+
7
+ #include "ruby.h"
8
+ #include "rubyio.h"
9
+
10
+ #define EV_STANDALONE 1
11
+ #include "../libev/ev.h"
12
+
13
+ #include "rev.h"
14
+ #include "rev_watcher.h"
15
+
16
+ /* Module and object handles */
17
+ static VALUE mRev = Qnil;
18
+ static VALUE cRev_Watcher = Qnil;
19
+ static VALUE cRev_Loop = Qnil;
20
+ static VALUE cRev_IOWatcher = Qnil;
21
+
22
+ /* Method implementations */
23
+ static VALUE Rev_IOWatcher_initialize(int argc, VALUE *argv, VALUE self);
24
+ static VALUE Rev_IOWatcher_attach(VALUE self, VALUE loop);
25
+ static VALUE Rev_IOWatcher_detach(VALUE self);
26
+ static VALUE Rev_IOWatcher_enable(VALUE self);
27
+ static VALUE Rev_IOWatcher_disable(VALUE self);
28
+ static VALUE Rev_IOWatcher_on_readable(VALUE self);
29
+ static VALUE Rev_IOWatcher_on_writable(VALUE self);
30
+
31
+ /* Callbacks */
32
+ static void Rev_IOWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
33
+ static void Rev_IOWatcher_dispatch_callback(VALUE self, int revents);
34
+
35
+ void Init_rev_io_watcher()
36
+ {
37
+ mRev = rb_define_module("Rev");
38
+ cRev_Watcher = rb_define_class_under(mRev, "Watcher", rb_cObject);
39
+ cRev_IOWatcher = rb_define_class_under(mRev, "IOWatcher", cRev_Watcher);
40
+ cRev_Loop = rb_define_class_under(mRev, "Loop", rb_cObject);
41
+
42
+ rb_define_method(cRev_IOWatcher, "initialize", Rev_IOWatcher_initialize, -1);
43
+ rb_define_method(cRev_IOWatcher, "attach", Rev_IOWatcher_attach, 1);
44
+ rb_define_method(cRev_IOWatcher, "detach", Rev_IOWatcher_detach, 0);
45
+ rb_define_method(cRev_IOWatcher, "enable", Rev_IOWatcher_enable, 0);
46
+ rb_define_method(cRev_IOWatcher, "disable", Rev_IOWatcher_disable, 0);
47
+ rb_define_method(cRev_IOWatcher, "on_readable", Rev_IOWatcher_on_readable, 0);
48
+ rb_define_method(cRev_IOWatcher, "on_writable", Rev_IOWatcher_on_writable, 0);
49
+ }
50
+
51
+ /**
52
+ * call-seq:
53
+ * Rev::IOWatcher.initialize(IO, events = 'r') -> Rev::IOWatcher
54
+ *
55
+ * Create a new Rev::IOWatcher for the given IO object and add it to the given Rev::Loop
56
+ */
57
+ static VALUE Rev_IOWatcher_initialize(int argc, VALUE *argv, VALUE self)
58
+ {
59
+ VALUE io, flags;
60
+ char *flags_str;
61
+ int events;
62
+ rb_io_t *fptr;
63
+ struct Rev_Watcher *watcher_data;
64
+
65
+ rb_scan_args(argc, argv, "11", &io, &flags);
66
+
67
+ if(flags != Qnil)
68
+ flags_str = RSTRING_PTR(rb_String(flags));
69
+ else
70
+ flags_str = "r";
71
+
72
+ if(!strcmp(flags_str, "r"))
73
+ events = EV_READ;
74
+ else if(!strcmp(flags_str, "w"))
75
+ events = EV_WRITE;
76
+ else if(!strcmp(flags_str, "rw"))
77
+ events = EV_READ | EV_WRITE;
78
+ else
79
+ rb_raise(rb_eArgError, "invalid event type: '%s' (must be 'r', 'w', or 'rw')", flags_str);
80
+
81
+ GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
82
+ Data_Get_Struct(self, struct Rev_Watcher, watcher_data);
83
+
84
+ watcher_data->dispatch_callback = Rev_IOWatcher_dispatch_callback;
85
+ ev_io_init(&watcher_data->event_types.ev_io, Rev_IOWatcher_libev_callback, fptr->fd, events);
86
+ watcher_data->event_types.ev_io.data = (void *)self;
87
+
88
+ return Qnil;
89
+ }
90
+
91
+ static VALUE Rev_IOWatcher_attach(VALUE self, VALUE loop)
92
+ {
93
+ Watcher_Attach(io, Rev_IOWatcher_detach, self, loop);
94
+
95
+ return self;
96
+ }
97
+
98
+ static VALUE Rev_IOWatcher_detach(VALUE self)
99
+ {
100
+ Watcher_Detach(io, self);
101
+
102
+ return self;
103
+ }
104
+
105
+ static VALUE Rev_IOWatcher_enable(VALUE self)
106
+ {
107
+ Watcher_Enable(io, self);
108
+
109
+ return self;
110
+ }
111
+
112
+ static VALUE Rev_IOWatcher_disable(VALUE self)
113
+ {
114
+ Watcher_Disable(io, self);
115
+
116
+ return self;
117
+ }
118
+
119
+ /**
120
+ * call-seq:
121
+ * Rev::IOWatcher#on_readable -> nil
122
+ *
123
+ * Called whenever the IO object associated with the IOWatcher is readable
124
+ */
125
+ static VALUE Rev_IOWatcher_on_readable(VALUE self)
126
+ {
127
+ return Qnil;
128
+ }
129
+
130
+ /**
131
+ * call-seq:
132
+ * Rev::IOWatcher#on_writable -> nil
133
+ *
134
+ * Called whenever the IO object associated with the IOWatcher is writable
135
+ */
136
+
137
+ static VALUE Rev_IOWatcher_on_writable(VALUE self)
138
+ {
139
+ return Qnil;
140
+ }
141
+
142
+ /* libev callback */
143
+ static void Rev_IOWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents)
144
+ {
145
+ Rev_Loop_process_event((VALUE)io->data, revents);
146
+ }
147
+
148
+ /* Rev::Loop dispatch callback */
149
+ static void Rev_IOWatcher_dispatch_callback(VALUE self, int revents)
150
+ {
151
+ if(revents & EV_READ)
152
+ rb_funcall(self, rb_intern("on_readable"), 0, 0);
153
+ else if(revents & EV_WRITE)
154
+ rb_funcall(self, rb_intern("on_writable"), 0, 0);
155
+ else
156
+ rb_raise(rb_eRuntimeError, "unknown revents value for ev_io: %d", revents);
157
+ }