eventmachine-eventmachine 0.12.3 → 0.12.4

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