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.
- data/Rakefile +31 -9
- data/ext/cmain.cpp +23 -9
- data/ext/ed.cpp +40 -24
- data/ext/ed.h +9 -2
- data/ext/em.cpp +28 -6
- data/ext/em.h +7 -0
- data/ext/extconf.rb +1 -1
- data/ext/fastfilereader/extconf.rb +161 -0
- data/ext/fastfilereader/mapper.cpp +202 -0
- data/ext/fastfilereader/mapper.h +59 -0
- data/ext/fastfilereader/rubymain.cpp +127 -0
- data/ext/pipe.cpp +13 -6
- data/ext/rubymain.cpp +49 -0
- data/lib/eventmachine.rb +9 -4
- data/lib/eventmachine_version.rb +1 -1
- data/lib/protocols/httpcli2.rb +4 -4
- data/lib/protocols/line_and_text.rb +5 -1
- data/lib/protocols/linetext2.rb +11 -13
- data/lib/protocols/stomp.rb +23 -0
- data/tests/test_epoll.rb +3 -1
- data/tests/test_httpclient2.rb +27 -5
- data/tests/test_ltp.rb +0 -4
- data/tests/test_send_file.rb +0 -2
- data/tests/test_smtpclient.rb +45 -43
- metadata +7 -2
@@ -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,
|
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
|
-
|
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
|
|