eventmachine-eventmachine 0.12.3 → 0.12.4

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,202 @@
1
+ /*****************************************************************************
2
+
3
+ $Id: mapper.cpp 4527 2007-07-04 10:21:34Z francis $
4
+
5
+ File: mapper.cpp
6
+ Date: 02Jul07
7
+
8
+ Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: garbagecat10
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+
21
+ //////////////////////////////////////////////////////////////////////
22
+ // UNIX implementation
23
+ //////////////////////////////////////////////////////////////////////
24
+
25
+
26
+ #ifdef OS_UNIX
27
+
28
+ #include <sys/types.h>
29
+ #include <sys/stat.h>
30
+ #include <sys/mman.h>
31
+ #include <fcntl.h>
32
+ #include <errno.h>
33
+
34
+ #include <iostream>
35
+ #include "unistd.h"
36
+ #include <string>
37
+ #include <cstring>
38
+ #include <stdexcept>
39
+ using namespace std;
40
+
41
+ #include "mapper.h"
42
+
43
+ /******************
44
+ Mapper_t::Mapper_t
45
+ ******************/
46
+
47
+ Mapper_t::Mapper_t (const string &filename)
48
+ {
49
+ /* We ASSUME we can open the file.
50
+ * (More precisely, we assume someone else checked before we got here.)
51
+ */
52
+
53
+ Fd = open (filename.c_str(), O_RDONLY);
54
+ if (Fd < 0)
55
+ throw runtime_error (strerror (errno));
56
+
57
+ struct stat st;
58
+ if (fstat (Fd, &st))
59
+ throw runtime_error (strerror (errno));
60
+ FileSize = st.st_size;
61
+
62
+ MapPoint = (const char*) mmap (0, FileSize, PROT_READ, MAP_SHARED, Fd, 0);
63
+ if (MapPoint == MAP_FAILED)
64
+ throw runtime_error (strerror (errno));
65
+ }
66
+
67
+
68
+ /*******************
69
+ Mapper_t::~Mapper_t
70
+ *******************/
71
+
72
+ Mapper_t::~Mapper_t()
73
+ {
74
+ Close();
75
+ }
76
+
77
+
78
+ /***************
79
+ Mapper_t::Close
80
+ ***************/
81
+
82
+ void Mapper_t::Close()
83
+ {
84
+ // Can be called multiple times.
85
+ // Calls to GetChunk are invalid after a call to Close.
86
+ if (MapPoint) {
87
+ munmap ((void*)MapPoint, FileSize);
88
+ MapPoint = NULL;
89
+ }
90
+ if (Fd >= 0) {
91
+ close (Fd);
92
+ Fd = -1;
93
+ }
94
+ }
95
+
96
+ /******************
97
+ Mapper_t::GetChunk
98
+ ******************/
99
+
100
+ const char *Mapper_t::GetChunk (unsigned start)
101
+ {
102
+ return MapPoint + start;
103
+ }
104
+
105
+
106
+
107
+ #endif // OS_UNIX
108
+
109
+
110
+ //////////////////////////////////////////////////////////////////////
111
+ // WINDOWS implementation
112
+ //////////////////////////////////////////////////////////////////////
113
+
114
+ #ifdef OS_WIN32
115
+
116
+ #include <windows.h>
117
+
118
+ #include <iostream>
119
+ #include <string>
120
+ #include <stdexcept>
121
+ using namespace std;
122
+
123
+ #include "mapper.h"
124
+
125
+ /******************
126
+ Mapper_t::Mapper_t
127
+ ******************/
128
+
129
+ Mapper_t::Mapper_t (const string &filename)
130
+ {
131
+ /* We ASSUME we can open the file.
132
+ * (More precisely, we assume someone else checked before we got here.)
133
+ */
134
+
135
+ hFile = INVALID_HANDLE_VALUE;
136
+ hMapping = NULL;
137
+ MapPoint = NULL;
138
+ FileSize = 0;
139
+
140
+ hFile = CreateFile (filename.c_str(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
141
+
142
+ if (hFile == INVALID_HANDLE_VALUE)
143
+ throw runtime_error ("File not found");
144
+
145
+ BY_HANDLE_FILE_INFORMATION i;
146
+ if (GetFileInformationByHandle (hFile, &i))
147
+ FileSize = i.nFileSizeLow;
148
+
149
+ hMapping = CreateFileMapping (hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
150
+ if (!hMapping)
151
+ throw runtime_error ("File not mapped");
152
+
153
+ MapPoint = (const char*) MapViewOfFile (hMapping, FILE_MAP_WRITE, 0, 0, 0);
154
+ if (!MapPoint)
155
+ throw runtime_error ("Mappoint not read");
156
+ }
157
+
158
+
159
+ /*******************
160
+ Mapper_t::~Mapper_t
161
+ *******************/
162
+
163
+ Mapper_t::~Mapper_t()
164
+ {
165
+ Close();
166
+ }
167
+
168
+ /***************
169
+ Mapper_t::Close
170
+ ***************/
171
+
172
+ void Mapper_t::Close()
173
+ {
174
+ // Can be called multiple times.
175
+ // Calls to GetChunk are invalid after a call to Close.
176
+ if (MapPoint) {
177
+ UnmapViewOfFile (MapPoint);
178
+ MapPoint = NULL;
179
+ }
180
+ if (hMapping != NULL) {
181
+ CloseHandle (hMapping);
182
+ hMapping = NULL;
183
+ }
184
+ if (hFile != INVALID_HANDLE_VALUE) {
185
+ CloseHandle (hFile);
186
+ hMapping = INVALID_HANDLE_VALUE;
187
+ }
188
+ }
189
+
190
+
191
+ /******************
192
+ Mapper_t::GetChunk
193
+ ******************/
194
+
195
+ const char *Mapper_t::GetChunk (unsigned start)
196
+ {
197
+ return MapPoint + start;
198
+ }
199
+
200
+
201
+
202
+ #endif // OS_WINDOWS
@@ -0,0 +1,59 @@
1
+ /*****************************************************************************
2
+
3
+ $Id: mapper.h 4529 2007-07-04 11:32:22Z francis $
4
+
5
+ File: mapper.h
6
+ Date: 02Jul07
7
+
8
+ Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: garbagecat10
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+
21
+ #ifndef __Mapper__H_
22
+ #define __Mapper__H_
23
+
24
+
25
+ /**************
26
+ class Mapper_t
27
+ **************/
28
+
29
+ class Mapper_t
30
+ {
31
+ public:
32
+ Mapper_t (const string&);
33
+ virtual ~Mapper_t();
34
+
35
+ const char *GetChunk (unsigned);
36
+ void Close();
37
+ size_t GetFileSize() {return FileSize;}
38
+
39
+ private:
40
+ size_t FileSize;
41
+
42
+ #ifdef OS_UNIX
43
+ private:
44
+ int Fd;
45
+ const char *MapPoint;
46
+ #endif // OS_UNIX
47
+
48
+ #ifdef OS_WIN32
49
+ private:
50
+ HANDLE hFile;
51
+ HANDLE hMapping;
52
+ const char *MapPoint;
53
+ #endif // OS_WIN32
54
+
55
+ };
56
+
57
+
58
+ #endif // __Mapper__H_
59
+
@@ -0,0 +1,127 @@
1
+ /*****************************************************************************
2
+
3
+ $Id: rubymain.cpp 4529 2007-07-04 11:32:22Z francis $
4
+
5
+ File: rubymain.cpp
6
+ Date: 02Jul07
7
+
8
+ Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: garbagecat10
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+
21
+
22
+ #include <iostream>
23
+ #include <stdexcept>
24
+ using namespace std;
25
+
26
+ #include <ruby.h>
27
+ #include "mapper.h"
28
+
29
+ static VALUE EmModule;
30
+ static VALUE FastFileReader;
31
+ static VALUE Mapper;
32
+
33
+
34
+
35
+ /*********
36
+ mapper_dt
37
+ *********/
38
+
39
+ static void mapper_dt (void *ptr)
40
+ {
41
+ if (ptr)
42
+ delete (Mapper_t*) ptr;
43
+ }
44
+
45
+ /**********
46
+ mapper_new
47
+ **********/
48
+
49
+ static VALUE mapper_new (VALUE self, VALUE filename)
50
+ {
51
+ Mapper_t *m = new Mapper_t (StringValuePtr (filename));
52
+ if (!m)
53
+ rb_raise (rb_eException, "No Mapper Object");
54
+ VALUE v = Data_Wrap_Struct (Mapper, 0, mapper_dt, (void*)m);
55
+ return v;
56
+ }
57
+
58
+
59
+ /****************
60
+ mapper_get_chunk
61
+ ****************/
62
+
63
+ static VALUE mapper_get_chunk (VALUE self, VALUE start, VALUE length)
64
+ {
65
+ Mapper_t *m = NULL;
66
+ Data_Get_Struct (self, Mapper_t, m);
67
+ if (!m)
68
+ rb_raise (rb_eException, "No Mapper Object");
69
+
70
+ // TODO, what if some moron sends us a negative start value?
71
+ unsigned _start = NUM2INT (start);
72
+ unsigned _length = NUM2INT (length);
73
+ if ((_start + _length) > m->GetFileSize())
74
+ rb_raise (rb_eException, "Mapper Range Error");
75
+
76
+ const char *chunk = m->GetChunk (_start);
77
+ if (!chunk)
78
+ rb_raise (rb_eException, "No Mapper Chunk");
79
+ return rb_str_new (chunk, _length);
80
+ }
81
+
82
+ /************
83
+ mapper_close
84
+ ************/
85
+
86
+ static VALUE mapper_close (VALUE self)
87
+ {
88
+ Mapper_t *m = NULL;
89
+ Data_Get_Struct (self, Mapper_t, m);
90
+ if (!m)
91
+ rb_raise (rb_eException, "No Mapper Object");
92
+ m->Close();
93
+ return Qnil;
94
+ }
95
+
96
+ /***********
97
+ mapper_size
98
+ ***********/
99
+
100
+ static VALUE mapper_size (VALUE self)
101
+ {
102
+ Mapper_t *m = NULL;
103
+ Data_Get_Struct (self, Mapper_t, m);
104
+ if (!m)
105
+ rb_raise (rb_eException, "No Mapper Object");
106
+ return INT2NUM (m->GetFileSize());
107
+ }
108
+
109
+
110
+ /**********************
111
+ Init_fastfilereaderext
112
+ **********************/
113
+
114
+ extern "C" void Init_fastfilereaderext()
115
+ {
116
+ EmModule = rb_define_module ("EventMachine");
117
+ FastFileReader = rb_define_class_under (EmModule, "FastFileReader", rb_cObject);
118
+ Mapper = rb_define_class_under (FastFileReader, "Mapper", rb_cObject);
119
+
120
+ rb_define_module_function (Mapper, "new", (VALUE(*)(...))mapper_new, 1);
121
+ rb_define_method (Mapper, "size", (VALUE(*)(...))mapper_size, 0);
122
+ rb_define_method (Mapper, "close", (VALUE(*)(...))mapper_close, 0);
123
+ rb_define_method (Mapper, "get_chunk", (VALUE(*)(...))mapper_get_chunk, 2);
124
+ }
125
+
126
+
127
+
data/ext/pipe.cpp CHANGED
@@ -92,15 +92,22 @@ PipeDescriptor::~PipeDescriptor()
92
92
  * within other unbind calls. (Not sure if that's even possible.)
93
93
  */
94
94
 
95
- struct timespec req = {0, 500000000};
96
- kill (SubprocessPid, SIGTERM);
97
- nanosleep (&req, NULL);
98
95
  assert (MyEventMachine);
96
+
97
+ // check if the process is already dead
99
98
  if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) == 0) {
100
- kill (SubprocessPid, SIGKILL);
99
+ kill (SubprocessPid, SIGTERM);
100
+ // wait 0.25s for process to die
101
+ struct timespec req = {0, 250000000};
101
102
  nanosleep (&req, NULL);
102
- if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) == 0)
103
- throw std::runtime_error ("unable to reap subprocess");
103
+ if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) == 0) {
104
+ kill (SubprocessPid, SIGKILL);
105
+ // wait 0.5s for process to die
106
+ struct timespec req = {0, 500000000};
107
+ nanosleep (&req, NULL);
108
+ if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) == 0)
109
+ throw std::runtime_error ("unable to reap subprocess");
110
+ }
104
111
  }
105
112
  }
106
113
 
data/ext/rubymain.cpp CHANGED
@@ -515,6 +515,20 @@ static VALUE t__epoll (VALUE self)
515
515
  return Qnil;
516
516
  }
517
517
 
518
+ /**********
519
+ t__epoll_p
520
+ **********/
521
+
522
+ static VALUE t__epoll_p (VALUE self)
523
+ {
524
+ #ifdef HAVE_EPOLL
525
+ return Qtrue;
526
+ #else
527
+ return Qfalse;
528
+ #endif
529
+ }
530
+
531
+
518
532
  /*********
519
533
  t__kqueue
520
534
  *********/
@@ -526,6 +540,19 @@ static VALUE t__kqueue (VALUE self)
526
540
  return Qnil;
527
541
  }
528
542
 
543
+ /***********
544
+ t__kqueue_p
545
+ ***********/
546
+
547
+ static VALUE t__kqueue_p (VALUE self)
548
+ {
549
+ #ifdef HAVE_KQUEUE
550
+ return Qtrue;
551
+ #else
552
+ return Qfalse;
553
+ #endif
554
+ }
555
+
529
556
 
530
557
  /****************
531
558
  t_send_file_data
@@ -590,6 +617,23 @@ static VALUE conn_associate_callback_target (VALUE self, VALUE sig)
590
617
  }
591
618
 
592
619
 
620
+ /***************
621
+ t_get_loop_time
622
+ ****************/
623
+
624
+ static VALUE t_get_loop_time (VALUE self)
625
+ {
626
+ VALUE cTime = rb_path2class("Time");
627
+ if (gCurrentLoopTime != 0) {
628
+ return rb_funcall(cTime,
629
+ rb_intern("at"),
630
+ 1,
631
+ INT2NUM(gCurrentLoopTime));
632
+ }
633
+ return Qnil;
634
+ }
635
+
636
+
593
637
  /*********************
594
638
  Init_rubyeventmachine
595
639
  *********************/
@@ -639,6 +683,8 @@ extern "C" void Init_rubyeventmachine()
639
683
  rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 3);
640
684
  rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1);
641
685
 
686
+ rb_define_module_function (EmModule, "current_time", (VALUE(*)(...))t_get_loop_time, 0);
687
+
642
688
  rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2);
643
689
  rb_define_module_function (EmModule, "read_keyboard", (VALUE(*)(...))t_read_keyboard, 0);
644
690
  rb_define_module_function (EmModule, "release_machine", (VALUE(*)(...))t_release_machine, 0);
@@ -666,6 +712,9 @@ extern "C" void Init_rubyeventmachine()
666
712
  rb_define_module_function (EmModule, "epoll", (VALUE(*)(...))t__epoll, 0);
667
713
  rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0);
668
714
 
715
+ rb_define_module_function (EmModule, "epoll?", (VALUE(*)(...))t__epoll_p, 0);
716
+ rb_define_module_function (EmModule, "kqueue?", (VALUE(*)(...))t__kqueue_p, 0);
717
+
669
718
  rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0);
670
719
  rb_define_method (EmConnection, "associate_callback_target", (VALUE(*)(...))conn_associate_callback_target, 1);
671
720