rev 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libev win32 compatibility cruft (_not_ a backend)
3
3
  *
4
- * Copyright (c) 2007,2008 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
@@ -55,7 +55,7 @@ ev_pipe (int filedes [2])
55
55
  struct sockaddr_in addr = { 0 };
56
56
  int addr_size = sizeof (addr);
57
57
  struct sockaddr_in adr2;
58
- int adr2_size;
58
+ int adr2_size = sizeof (adr2);
59
59
  SOCKET listener;
60
60
  SOCKET sock [2] = { -1, -1 };
61
61
 
@@ -133,22 +133,21 @@ fail:
133
133
 
134
134
  #undef pipe
135
135
  #define pipe(filedes) ev_pipe (filedes)
136
-
137
- static int
138
- ev_gettimeofday (struct timeval *tv, struct timezone *tz)
136
+
137
+ #define EV_HAVE_EV_TIME 1
138
+ ev_tstamp
139
+ ev_time (void)
139
140
  {
140
- struct _timeb tb;
141
-
142
- _ftime (&tb);
141
+ FILETIME ft;
142
+ ULARGE_INTEGER ui;
143
143
 
144
- tv->tv_sec = (long)tb.time;
145
- tv->tv_usec = ((long)tb.millitm) * 1000;
144
+ GetSystemTimeAsFileTime (&ft);
145
+ ui.u.LowPart = ft.dwLowDateTime;
146
+ ui.u.HighPart = ft.dwHighDateTime;
146
147
 
147
- return 0;
148
+ /* msvc cannot convert ulonglong to double... yes, it is that sucky */
149
+ return (LONGLONG)(ui.QuadPart - 116444736000000000) * 1e-7;
148
150
  }
149
151
 
150
- #undef gettimeofday
151
- #define gettimeofday(tv,tz) ev_gettimeofday (tv, tz)
152
-
153
152
  #endif
154
153
 
@@ -8,14 +8,23 @@
8
8
  #define timeout_blocktime ((loop)->timeout_blocktime)
9
9
  #define backend ((loop)->backend)
10
10
  #define activecnt ((loop)->activecnt)
11
- #define loop_count ((loop)->loop_count)
11
+ #define loop_done ((loop)->loop_done)
12
12
  #define backend_fd ((loop)->backend_fd)
13
13
  #define backend_fudge ((loop)->backend_fudge)
14
14
  #define backend_modify ((loop)->backend_modify)
15
15
  #define backend_poll ((loop)->backend_poll)
16
+ #define anfds ((loop)->anfds)
17
+ #define anfdmax ((loop)->anfdmax)
18
+ #define pendings ((loop)->pendings)
19
+ #define pendingmax ((loop)->pendingmax)
20
+ #define pendingcnt ((loop)->pendingcnt)
21
+ #define pending_w ((loop)->pending_w)
22
+ #define rfeeds ((loop)->rfeeds)
23
+ #define rfeedmax ((loop)->rfeedmax)
24
+ #define rfeedcnt ((loop)->rfeedcnt)
16
25
  #define evfd ((loop)->evfd)
17
26
  #define evpipe ((loop)->evpipe)
18
- #define pipeev ((loop)->pipeev)
27
+ #define pipe_w ((loop)->pipe_w)
19
28
  #define curpid ((loop)->curpid)
20
29
  #define postfork ((loop)->postfork)
21
30
  #define vec_ri ((loop)->vec_ri)
@@ -38,11 +47,6 @@
38
47
  #define kqueue_eventmax ((loop)->kqueue_eventmax)
39
48
  #define port_events ((loop)->port_events)
40
49
  #define port_eventmax ((loop)->port_eventmax)
41
- #define anfds ((loop)->anfds)
42
- #define anfdmax ((loop)->anfdmax)
43
- #define pendings ((loop)->pendings)
44
- #define pendingmax ((loop)->pendingmax)
45
- #define pendingcnt ((loop)->pendingcnt)
46
50
  #define fdchanges ((loop)->fdchanges)
47
51
  #define fdchangemax ((loop)->fdchangemax)
48
52
  #define fdchangecnt ((loop)->fdchangecnt)
@@ -65,7 +69,7 @@
65
69
  #define forks ((loop)->forks)
66
70
  #define forkmax ((loop)->forkmax)
67
71
  #define forkcnt ((loop)->forkcnt)
68
- #define gotasync ((loop)->gotasync)
72
+ #define async_pending ((loop)->async_pending)
69
73
  #define asyncs ((loop)->asyncs)
70
74
  #define asyncmax ((loop)->asyncmax)
71
75
  #define asynccnt ((loop)->asynccnt)
@@ -73,6 +77,16 @@
73
77
  #define fs_w ((loop)->fs_w)
74
78
  #define fs_2625 ((loop)->fs_2625)
75
79
  #define fs_hash ((loop)->fs_hash)
80
+ #define sig_pending ((loop)->sig_pending)
81
+ #define sigfd ((loop)->sigfd)
82
+ #define sigfd_w ((loop)->sigfd_w)
83
+ #define sigfd_set ((loop)->sigfd_set)
84
+ #define loop_count ((loop)->loop_count)
85
+ #define loop_depth ((loop)->loop_depth)
86
+ #define userdata ((loop)->userdata)
87
+ #define release_cb ((loop)->release_cb)
88
+ #define acquire_cb ((loop)->acquire_cb)
89
+ #define invoke_cb ((loop)->invoke_cb)
76
90
  #else
77
91
  #undef EV_WRAP_H
78
92
  #undef now_floor
@@ -82,14 +96,23 @@
82
96
  #undef timeout_blocktime
83
97
  #undef backend
84
98
  #undef activecnt
85
- #undef loop_count
99
+ #undef loop_done
86
100
  #undef backend_fd
87
101
  #undef backend_fudge
88
102
  #undef backend_modify
89
103
  #undef backend_poll
104
+ #undef anfds
105
+ #undef anfdmax
106
+ #undef pendings
107
+ #undef pendingmax
108
+ #undef pendingcnt
109
+ #undef pending_w
110
+ #undef rfeeds
111
+ #undef rfeedmax
112
+ #undef rfeedcnt
90
113
  #undef evfd
91
114
  #undef evpipe
92
- #undef pipeev
115
+ #undef pipe_w
93
116
  #undef curpid
94
117
  #undef postfork
95
118
  #undef vec_ri
@@ -112,11 +135,6 @@
112
135
  #undef kqueue_eventmax
113
136
  #undef port_events
114
137
  #undef port_eventmax
115
- #undef anfds
116
- #undef anfdmax
117
- #undef pendings
118
- #undef pendingmax
119
- #undef pendingcnt
120
138
  #undef fdchanges
121
139
  #undef fdchangemax
122
140
  #undef fdchangecnt
@@ -139,7 +157,7 @@
139
157
  #undef forks
140
158
  #undef forkmax
141
159
  #undef forkcnt
142
- #undef gotasync
160
+ #undef async_pending
143
161
  #undef asyncs
144
162
  #undef asyncmax
145
163
  #undef asynccnt
@@ -147,4 +165,14 @@
147
165
  #undef fs_w
148
166
  #undef fs_2625
149
167
  #undef fs_hash
168
+ #undef sig_pending
169
+ #undef sigfd
170
+ #undef sigfd_w
171
+ #undef sigfd_set
172
+ #undef loop_count
173
+ #undef loop_depth
174
+ #undef userdata
175
+ #undef release_cb
176
+ #undef acquire_cb
177
+ #undef invoke_cb
150
178
  #endif
@@ -36,7 +36,7 @@ if have_header('port.h')
36
36
  $defs << '-DEV_USE_PORT'
37
37
  end
38
38
 
39
- if have_header('openssl/ssl.h')
39
+ if have_header('openssl/ssl.h') and RUBY_PLATFORM !~ /mingw|win32/ # win32 and SSL no go currently...needs some help to work
40
40
  $defs << '-DHAVE_OPENSSL_SSL_H'
41
41
  libs << '-lssl -lcrypto'
42
42
  end
@@ -60,11 +60,11 @@ $LIBS << ' ' << libs.join(' ')
60
60
  dir_config('rev_ext')
61
61
  create_makefile('rev_ext')
62
62
 
63
- if have_header('openssl/ssl.h') and RUBY_PLATFORM =~ /mingw|win32/
64
- print "Note--SSL not yet supported on windows--continuing without SSL support"
63
+ # win32 needs to link in "just the right order" for some reason or ioctlsocket will be mapped to an [inverted] ruby specific version. See libev mailing list for (not so helpful discussion--true cause I'm not sure, but this overcomes the symptom)
64
+ if RUBY_PLATFORM =~ /mingw|win32/
65
65
  makefile_contents = File.read 'Makefile'
66
- makefile_contents.gsub!('-DHAVE_OPENSSL_SSL_H', '')
67
- makefile_contents.gsub! 'LIBS = $(LIBRUBYARG_SHARED)', 'LIBS = -lws2_32 $(LIBRUBYARG_SHARED)' # for some reason has to come first or ioctlsocket will be mapped to an [inverted] ruby specific version
68
66
 
67
+ makefile_contents.gsub! 'LIBS = $(LIBRUBYARG_SHARED)', 'LIBS = -lws2_32 $(LIBRUBYARG_SHARED)'
69
68
  File.open('Makefile', 'w') { |f| f.write makefile_contents }
70
69
  end
70
+
@@ -44,6 +44,7 @@ struct Rev_Watcher
44
44
  union {
45
45
  struct ev_io ev_io;
46
46
  struct ev_timer ev_timer;
47
+ struct ev_stat ev_stat;
47
48
  } event_types;
48
49
 
49
50
  int enabled;
@@ -16,14 +16,12 @@ static VALUE mRev = Qnil;
16
16
 
17
17
  void Init_rev_ext()
18
18
  {
19
- ev_set_allocator((void *(*)(void *, long))xrealloc);
20
-
21
19
  /* Initializers for other modules */
22
20
  Init_rev_loop();
23
21
  Init_rev_watcher();
24
22
  Init_rev_io_watcher();
25
23
  Init_rev_timer_watcher();
26
- Init_rev_buffer();
24
+ Init_rev_stat_watcher();
27
25
  Init_rev_utils();
28
26
 
29
27
  #ifdef HAVE_OPENSSL_SSL_H
@@ -32,8 +32,6 @@ static void Rev_IOWatcher_dispatch_callback(VALUE self, int revents);
32
32
  * Rev::IOWatcher monitors Ruby IO objects for readability or writability.
33
33
  * This allows your application to block while the kernel is writing out
34
34
  * data and fill the read or write buffer whenever there is space available.
35
- * It's used by the Rev::BufferedIO class to provide high performace I/O
36
- * which is bound by the kernel's ability to read and write data.
37
35
  */
38
36
  void Init_rev_io_watcher()
39
37
  {
@@ -0,0 +1,182 @@
1
+ /*
2
+ * Copyright (C) 2009 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
+ #include "ev_wrap.h"
10
+
11
+ #include "rev.h"
12
+ #include "rev_watcher.h"
13
+
14
+ static VALUE mRev = Qnil;
15
+ static VALUE cRev_Watcher = Qnil;
16
+ static VALUE cRev_StatWatcher = Qnil;
17
+ static VALUE cRev_Loop = Qnil;
18
+
19
+ static VALUE Rev_StatWatcher_initialize(VALUE self, VALUE path);
20
+ static VALUE Rev_StatWatcher_attach(VALUE self, VALUE loop);
21
+ static VALUE Rev_StatWatcher_detach(VALUE self);
22
+ static VALUE Rev_StatWatcher_enable(VALUE self);
23
+ static VALUE Rev_StatWatcher_disable(VALUE self);
24
+ static VALUE Rev_StatWatcher_on_change(VALUE self);
25
+ static VALUE Rev_StatWatcher_path(VALUE self);
26
+
27
+ static void Rev_StatWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_stat *stat, int revents);
28
+ static void Rev_StatWatcher_dispatch_callback(VALUE self, int revents);
29
+
30
+ /*
31
+ * Rev::StatWatcher lets you create either one-shot or periodic stats which
32
+ * run within Rev's event loop. It's useful for creating timeouts or
33
+ * events which fire periodically.
34
+ */
35
+ void Init_rev_stat_watcher()
36
+ {
37
+ mRev = rb_define_module("Rev");
38
+ cRev_Watcher = rb_define_class_under(mRev, "Watcher", rb_cObject);
39
+ cRev_StatWatcher = rb_define_class_under(mRev, "StatWatcher", cRev_Watcher);
40
+ cRev_Loop = rb_define_class_under(mRev, "Loop", rb_cObject);
41
+
42
+ rb_define_method(cRev_StatWatcher, "initialize", Rev_StatWatcher_initialize, 1);
43
+ rb_define_method(cRev_StatWatcher, "attach", Rev_StatWatcher_attach, 1);
44
+ rb_define_method(cRev_StatWatcher, "detach", Rev_StatWatcher_detach, 0);
45
+ rb_define_method(cRev_StatWatcher, "enable", Rev_StatWatcher_enable, 0);
46
+ rb_define_method(cRev_StatWatcher, "disable", Rev_StatWatcher_disable, 0);
47
+ rb_define_method(cRev_StatWatcher, "on_change", Rev_StatWatcher_on_change, 0);
48
+ rb_define_method(cRev_StatWatcher, "path", Rev_StatWatcher_path, 0);
49
+ }
50
+
51
+ /**
52
+ * call-seq:
53
+ * Rev::StatWatcher.initialize(path) -> Rev::StatWatcher
54
+ *
55
+ * Create a new Rev::StatWatcher for the given path. This will monitor the
56
+ * given path for changes at the filesystem level.
57
+ */
58
+ static VALUE Rev_StatWatcher_initialize(VALUE self, VALUE path)
59
+ {
60
+ struct Rev_Watcher *watcher_data;
61
+
62
+ path = rb_String(path);
63
+ rb_iv_set(self, "@path", path);
64
+
65
+ Data_Get_Struct(self, struct Rev_Watcher, watcher_data);
66
+
67
+ watcher_data->dispatch_callback = Rev_StatWatcher_dispatch_callback;
68
+ ev_stat_init(
69
+ &watcher_data->event_types.ev_stat,
70
+ Rev_StatWatcher_libev_callback,
71
+ RSTRING_PTR(path),
72
+ 0
73
+ );
74
+ watcher_data->event_types.ev_stat.data = (void *)self;
75
+
76
+ return Qnil;
77
+ }
78
+
79
+ /**
80
+ * call-seq:
81
+ * Rev::StatWatcher.attach(loop) -> Rev::StatWatcher
82
+ *
83
+ * Attach the stat watcher to the given Rev::Loop. If the watcher is already
84
+ * attached to a loop, detach it from the old one and attach it to the new one.
85
+ */
86
+ static VALUE Rev_StatWatcher_attach(VALUE self, VALUE loop)
87
+ {
88
+ ev_tstamp interval, timeout;
89
+ struct Rev_Loop *loop_data;
90
+ struct Rev_Watcher *watcher_data;
91
+
92
+ if(!rb_obj_is_kind_of(loop, cRev_Loop))
93
+ rb_raise(rb_eArgError, "expected loop to be an instance of Rev::Loop");
94
+
95
+ Data_Get_Struct(loop, struct Rev_Loop, loop_data);
96
+ Data_Get_Struct(self, struct Rev_Watcher, watcher_data);
97
+
98
+ if(watcher_data->loop != Qnil)
99
+ Rev_StatWatcher_detach(self);
100
+
101
+ watcher_data->loop = loop;
102
+
103
+ ev_stat_start(loop_data->ev_loop, &watcher_data->event_types.ev_stat);
104
+ rb_call_super(1, &loop);
105
+
106
+ return self;
107
+ }
108
+
109
+ /**
110
+ * call-seq:
111
+ * Rev::StatWatcher.detach -> Rev::StatWatcher
112
+ *
113
+ * Detach the stat watcher from its current Rev::Loop.
114
+ */
115
+ static VALUE Rev_StatWatcher_detach(VALUE self)
116
+ {
117
+ Watcher_Detach(stat, self);
118
+
119
+ return self;
120
+ }
121
+
122
+ /**
123
+ * call-seq:
124
+ * Rev::StatWatcher.enable -> Rev::StatWatcher
125
+ *
126
+ * Re-enable a stat watcher which has been temporarily disabled. See the
127
+ * disable method for a more thorough explanation.
128
+ */
129
+ static VALUE Rev_StatWatcher_enable(VALUE self)
130
+ {
131
+ Watcher_Enable(stat, self);
132
+
133
+ return self;
134
+ }
135
+
136
+ /**
137
+ * call-seq:
138
+ * Rev::StatWatcher.disable -> Rev::StatWatcher
139
+ *
140
+ * Temporarily disable a stat watcher which is attached to a loop.
141
+ * This is useful if you wish to toggle event monitoring on and off.
142
+ */
143
+ static VALUE Rev_StatWatcher_disable(VALUE self)
144
+ {
145
+ Watcher_Disable(stat, self);
146
+
147
+ return self;
148
+ }
149
+
150
+ /**
151
+ * call-seq:
152
+ * Rev::StatWatcher#on_change -> nil
153
+ *
154
+ * Called whenever the status of the given path changes
155
+ */
156
+ static VALUE Rev_StatWatcher_on_change(VALUE self)
157
+ {
158
+ return Qnil;
159
+ }
160
+
161
+ /**
162
+ * call-seq:
163
+ * Rev::StatWatcher#path -> String
164
+ *
165
+ * Retrieve the path associated with this StatWatcher
166
+ */
167
+ static VALUE Rev_StatWatcher_path(VALUE self)
168
+ {
169
+ return rb_iv_get(self, "@path");
170
+ }
171
+
172
+ /* libev callback */
173
+ static void Rev_StatWatcher_libev_callback(struct ev_loop *ev_loop, struct ev_stat *stat, int revents)
174
+ {
175
+ Rev_Loop_process_event((VALUE)stat->data, revents);
176
+ }
177
+
178
+ /* Rev::Loop dispatch callback */
179
+ static void Rev_StatWatcher_dispatch_callback(VALUE self, int revents)
180
+ {
181
+ rb_funcall(self, rb_intern("on_change"), 0, 0);
182
+ }
data/lib/rev.rb CHANGED
@@ -10,18 +10,17 @@ begin
10
10
  rescue LoadError
11
11
  end
12
12
 
13
- require File.dirname(__FILE__) + '/rev_ext'
14
- require File.dirname(__FILE__) + '/rev/loop'
15
- require File.dirname(__FILE__) + '/rev/meta'
16
- require File.dirname(__FILE__) + '/rev/io_watcher'
17
- require File.dirname(__FILE__) + '/rev/timer_watcher'
18
- require File.dirname(__FILE__) + '/rev/async_watcher'
19
- require File.dirname(__FILE__) + '/rev/listener'
20
- require File.dirname(__FILE__) + '/rev/io'
21
- require File.dirname(__FILE__) + '/rev/dns_resolver'
22
- require File.dirname(__FILE__) + '/rev/socket'
23
- require File.dirname(__FILE__) + '/rev/server'
24
- require File.dirname(__FILE__) + '/rev/http_client'
13
+ # Pull in iobuffer gem
14
+ require 'rubygems'
15
+ require 'iobuffer'
16
+
17
+ %w(
18
+ /rev_ext /rev/loop /rev/meta /rev/io_watcher /rev/timer_watcher
19
+ /rev/async_watcher /rev/listener /rev/io /rev/dns_resolver
20
+ /rev/socket /rev/server /rev/http_client
21
+ ).each do |file|
22
+ require File.dirname(__FILE__) + file
23
+ end
25
24
 
26
25
  module Rev
27
26
  Rev::VERSION = '0.2.3' unless defined? Rev::VERSION
@@ -24,8 +24,8 @@ module Rev
24
24
  # automatically detach themselves from the event loop and cannot be used
25
25
  # again.
26
26
  class DNSResolver < IOWatcher
27
- #--
28
- # TODO check if it's caching right
27
+ #--
28
+ # TODO check if it's caching right
29
29
  RESOLV_CONF = '/etc/resolv.conf'
30
30
  HOSTS = '/etc/hosts'
31
31
  DNS_PORT = 53
@@ -89,7 +89,7 @@ module Rev
89
89
 
90
90
  # Called if we don't receive a response, defaults to calling on_failure
91
91
  def on_timeout
92
- on_failure
92
+ on_failure
93
93
  end
94
94
 
95
95
  #########
@@ -102,9 +102,8 @@ module Rev
102
102
  @nameservers << nameserver # rotate them
103
103
  @socket.connect @nameservers.first, DNS_PORT
104
104
  begin
105
- @socket.send request_message, 0
105
+ @socket.send request_message, 0
106
106
  rescue Errno::EHOSTUNREACH # TODO figure out why it has to be wrapper here, when the other wrapper should be wrapping this one!
107
-
108
107
  end
109
108
  end
110
109
 
@@ -112,9 +111,10 @@ module Rev
112
111
  def on_readable
113
112
  datagram = nil
114
113
  begin
115
- datagram = @socket.recvfrom_nonblock(DATAGRAM_SIZE).first
114
+ datagram = @socket.recvfrom_nonblock(DATAGRAM_SIZE).first
116
115
  rescue Errno::ECONNREFUSED
117
116
  end
117
+
118
118
  address = response_address datagram rescue nil
119
119
  address ? on_success(address) : on_failure
120
120
  detach