rev 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }