ebb 0.2.0 → 0.2.1
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/benchmark/application.rb +8 -1
- data/libev/ev.c +612 -135
- data/libev/ev.h +76 -42
- data/libev/ev_epoll.c +1 -1
- data/libev/ev_kqueue.c +1 -1
- data/libev/ev_poll.c +18 -15
- data/libev/ev_port.c +1 -1
- data/libev/ev_select.c +25 -8
- data/libev/ev_vars.h +5 -2
- data/libev/ev_win32.c +1 -1
- data/libev/ev_wrap.h +2 -0
- data/ruby_lib/ebb.rb +37 -24
- data/src/ebb.c +15 -15
- data/src/ebb.h +3 -3
- data/src/ebb_ruby.c +20 -18
- metadata +13 -13
data/libev/ev.h
CHANGED
@@ -100,6 +100,8 @@ struct ev_loop;
|
|
100
100
|
# define EV_P_ EV_P,
|
101
101
|
# define EV_A loop
|
102
102
|
# define EV_A_ EV_A,
|
103
|
+
# define EV_DEFAULT_UC ev_default_loop_uc ()
|
104
|
+
# define EV_DEFAULT_UC_ EV_DEFAULT_UC,
|
103
105
|
# define EV_DEFAULT ev_default_loop (0)
|
104
106
|
# define EV_DEFAULT_ EV_DEFAULT,
|
105
107
|
#else
|
@@ -109,28 +111,37 @@ struct ev_loop;
|
|
109
111
|
# define EV_A_
|
110
112
|
# define EV_DEFAULT
|
111
113
|
# define EV_DEFAULT_
|
112
|
-
|
114
|
+
# define EV_DEFAULT_UC
|
115
|
+
# define EV_DEFAULT_UC_
|
113
116
|
# undef EV_EMBED_ENABLE
|
114
117
|
#endif
|
115
118
|
|
119
|
+
#if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3
|
120
|
+
# define EV_INLINE static inline
|
121
|
+
#else
|
122
|
+
# define EV_INLINE static
|
123
|
+
#endif
|
124
|
+
|
125
|
+
/*****************************************************************************/
|
126
|
+
|
116
127
|
/* eventmask, revents, events... */
|
117
|
-
#define EV_UNDEF -
|
118
|
-
#define EV_NONE
|
119
|
-
#define EV_READ
|
120
|
-
#define EV_WRITE
|
121
|
-
#define EV_IOFDSET
|
122
|
-
#define EV_TIMEOUT
|
123
|
-
#define EV_PERIODIC
|
124
|
-
#define EV_SIGNAL
|
125
|
-
#define EV_CHILD
|
126
|
-
#define EV_STAT
|
127
|
-
#define EV_IDLE
|
128
|
-
#define EV_PREPARE
|
129
|
-
#define EV_CHECK
|
130
|
-
#define EV_EMBED
|
131
|
-
#define EV_FORK
|
132
|
-
#define EV_ASYNC
|
133
|
-
#define EV_ERROR
|
128
|
+
#define EV_UNDEF -1 /* guaranteed to be invalid */
|
129
|
+
#define EV_NONE 0x00 /* no events */
|
130
|
+
#define EV_READ 0x01 /* ev_io detected read will not block */
|
131
|
+
#define EV_WRITE 0x02 /* ev_io detected write will not block */
|
132
|
+
#define EV_IOFDSET 0x80 /* internal use only */
|
133
|
+
#define EV_TIMEOUT 0x00000100 /* timer timed out */
|
134
|
+
#define EV_PERIODIC 0x00000200 /* periodic timer timed out */
|
135
|
+
#define EV_SIGNAL 0x00000400 /* signal was received */
|
136
|
+
#define EV_CHILD 0x00000800 /* child/pid had status change */
|
137
|
+
#define EV_STAT 0x00001000 /* stat data changed */
|
138
|
+
#define EV_IDLE 0x00002000 /* event loop is idling */
|
139
|
+
#define EV_PREPARE 0x00004000 /* event loop about to poll */
|
140
|
+
#define EV_CHECK 0x00008000 /* event loop finished poll */
|
141
|
+
#define EV_EMBED 0x00010000 /* embedded event loop needs sweep */
|
142
|
+
#define EV_FORK 0x00020000 /* event loop resumed in child */
|
143
|
+
#define EV_ASYNC 0x00040000 /* async intra-loop signal */
|
144
|
+
#define EV_ERROR 0x80000000 /* sent when an error occurs */
|
134
145
|
|
135
146
|
/* can be used to add custom fields to all watchers, while losing binary compatibility */
|
136
147
|
#ifndef EV_COMMON
|
@@ -155,6 +166,15 @@ struct ev_loop;
|
|
155
166
|
* private: you can look at them, but not change them, and they might not mean anything to you.
|
156
167
|
* ro: can be read anytime, but only changed when the watcher isn't active
|
157
168
|
* rw: can be read and modified anytime, even when the watcher is active
|
169
|
+
*
|
170
|
+
* some internal details that might be helpful for debugging:
|
171
|
+
*
|
172
|
+
* active is either 0, which means the watcher is not active,
|
173
|
+
* or the array index of the watcher (periodics, timers)
|
174
|
+
* or the array index + 1 (most other watchers)
|
175
|
+
* or simply 1 for watchers that aren't in some array.
|
176
|
+
* pending is either 0, in which case the watcher isn't,
|
177
|
+
* or the array index + 1 in the pendings array.
|
158
178
|
*/
|
159
179
|
|
160
180
|
/* shared by all watchers */
|
@@ -327,7 +347,7 @@ typedef struct ev_async
|
|
327
347
|
EV_ATOMIC_T sent; /* private */
|
328
348
|
} ev_async;
|
329
349
|
|
330
|
-
# define ev_async_pending(w) ((
|
350
|
+
# define ev_async_pending(w) ((w)->sent + 0)
|
331
351
|
#endif
|
332
352
|
|
333
353
|
/* the presence of this union forces similar struct layout */
|
@@ -355,24 +375,24 @@ union ev_any_watcher
|
|
355
375
|
#if EV_EMBED_ENABLE
|
356
376
|
struct ev_embed embed;
|
357
377
|
#endif
|
358
|
-
#if
|
378
|
+
#if EV_ASYNC_ENABLE
|
359
379
|
struct ev_async async;
|
360
380
|
#endif
|
361
381
|
};
|
362
382
|
|
363
383
|
/* bits for ev_default_loop and ev_loop_new */
|
364
384
|
/* the default */
|
365
|
-
#define EVFLAG_AUTO
|
385
|
+
#define EVFLAG_AUTO 0x00000000U /* not quite a mask */
|
366
386
|
/* flag bits */
|
367
|
-
#define EVFLAG_NOENV
|
368
|
-
#define EVFLAG_FORKCHECK
|
387
|
+
#define EVFLAG_NOENV 0x01000000U /* do NOT consult environment */
|
388
|
+
#define EVFLAG_FORKCHECK 0x02000000U /* check for a fork in each iteration */
|
369
389
|
/* method bits to be ored together */
|
370
|
-
#define EVBACKEND_SELECT
|
371
|
-
#define EVBACKEND_POLL
|
372
|
-
#define EVBACKEND_EPOLL
|
373
|
-
#define EVBACKEND_KQUEUE
|
374
|
-
#define EVBACKEND_DEVPOLL
|
375
|
-
#define EVBACKEND_PORT
|
390
|
+
#define EVBACKEND_SELECT 0x00000001U /* about anywhere */
|
391
|
+
#define EVBACKEND_POLL 0x00000002U /* !win */
|
392
|
+
#define EVBACKEND_EPOLL 0x00000004U /* linux */
|
393
|
+
#define EVBACKEND_KQUEUE 0x00000008U /* bsd */
|
394
|
+
#define EVBACKEND_DEVPOLL 0x00000010U /* solaris 8 */ /* NYI */
|
395
|
+
#define EVBACKEND_PORT 0x00000020U /* solaris 10 */
|
376
396
|
|
377
397
|
#if EV_PROTOTYPES
|
378
398
|
int ev_version_major (void);
|
@@ -399,42 +419,54 @@ void ev_set_allocator (void *(*cb)(void *ptr, long size));
|
|
399
419
|
*/
|
400
420
|
void ev_set_syserr_cb (void (*cb)(const char *msg));
|
401
421
|
|
402
|
-
#
|
422
|
+
#if EV_MULTIPLICITY
|
423
|
+
EV_INLINE struct ev_loop *
|
424
|
+
ev_default_loop_uc (void)
|
425
|
+
{
|
426
|
+
extern struct ev_loop *ev_default_loop_ptr;
|
427
|
+
|
428
|
+
return ev_default_loop_ptr;
|
429
|
+
}
|
430
|
+
|
403
431
|
/* the default loop is the only one that handles signals and child watchers */
|
404
432
|
/* you can call this as often as you like */
|
405
|
-
|
433
|
+
EV_INLINE struct ev_loop *
|
406
434
|
ev_default_loop (unsigned int flags)
|
407
435
|
{
|
408
|
-
|
409
|
-
extern struct ev_loop *ev_default_loop_init (unsigned int flags);
|
436
|
+
struct ev_loop *loop = ev_default_loop_uc ();
|
410
437
|
|
411
|
-
if (!
|
412
|
-
|
438
|
+
if (!loop)
|
439
|
+
{
|
440
|
+
extern struct ev_loop *ev_default_loop_init (unsigned int flags);
|
413
441
|
|
414
|
-
|
442
|
+
loop = ev_default_loop_init (flags);
|
443
|
+
}
|
444
|
+
|
445
|
+
return loop;
|
415
446
|
}
|
416
447
|
|
417
448
|
/* create and destroy alternative loops that don't handle signals */
|
418
449
|
struct ev_loop *ev_loop_new (unsigned int flags);
|
419
450
|
void ev_loop_destroy (EV_P);
|
420
451
|
void ev_loop_fork (EV_P);
|
452
|
+
void ev_loop_verify (EV_P);
|
421
453
|
|
422
454
|
ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */
|
423
455
|
|
424
|
-
#
|
456
|
+
#else
|
425
457
|
|
426
458
|
int ev_default_loop (unsigned int flags); /* returns true when successful */
|
427
459
|
|
428
|
-
|
460
|
+
EV_INLINE ev_tstamp
|
429
461
|
ev_now (void)
|
430
462
|
{
|
431
463
|
extern ev_tstamp ev_rt_now;
|
432
464
|
|
433
465
|
return ev_rt_now;
|
434
466
|
}
|
435
|
-
#
|
467
|
+
#endif /* multiplicity */
|
436
468
|
|
437
|
-
|
469
|
+
EV_INLINE int
|
438
470
|
ev_is_default_loop (EV_P)
|
439
471
|
{
|
440
472
|
#if EV_MULTIPLICITY
|
@@ -455,7 +487,7 @@ void ev_default_fork (void);
|
|
455
487
|
|
456
488
|
unsigned int ev_backend (EV_P); /* backend in use by loop */
|
457
489
|
unsigned int ev_loop_count (EV_P); /* number of loop iterations */
|
458
|
-
#endif
|
490
|
+
#endif /* prototypes */
|
459
491
|
|
460
492
|
#define EVLOOP_NONBLOCK 1 /* do not block/wait */
|
461
493
|
#define EVLOOP_ONESHOT 2 /* block *once* only */
|
@@ -493,7 +525,7 @@ void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revent
|
|
493
525
|
} while (0)
|
494
526
|
|
495
527
|
#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV_IOFDSET; } while (0)
|
496
|
-
#define ev_timer_set(ev,after_,repeat_) do { (ev)->at = (after_); (ev)->repeat = (repeat_); } while (0)
|
528
|
+
#define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
|
497
529
|
#define ev_periodic_set(ev,ofs_,ival_,res_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb= (res_); } while (0)
|
498
530
|
#define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0)
|
499
531
|
#define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
|
@@ -525,6 +557,8 @@ void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revent
|
|
525
557
|
#define ev_cb(ev) (ev)->cb /* rw */
|
526
558
|
#define ev_set_priority(ev,pri) ((ev_watcher *)(void *)(ev))->priority = (pri)
|
527
559
|
|
560
|
+
#define ev_periodic_at(ev) (((ev_watcher_time *)(ev))->at + 0.)
|
561
|
+
|
528
562
|
#ifndef ev_set_cb
|
529
563
|
# define ev_set_cb(ev,cb_) ev_cb (ev) = (cb_)
|
530
564
|
#endif
|
data/libev/ev_epoll.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* libev epoll fd activity backend
|
3
3
|
*
|
4
|
-
* Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
|
4
|
+
* Copyright (c) 2007,2008 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-
|
data/libev/ev_kqueue.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* libev kqueue backend
|
3
3
|
*
|
4
|
-
* Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
|
4
|
+
* Copyright (c) 2007,2008 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-
|
data/libev/ev_poll.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* libev poll fd activity backend
|
3
3
|
*
|
4
|
-
* Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
|
4
|
+
* Copyright (c) 2007,2008 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-
|
@@ -86,7 +86,7 @@ poll_modify (EV_P_ int fd, int oev, int nev)
|
|
86
86
|
static void
|
87
87
|
poll_poll (EV_P_ ev_tstamp timeout)
|
88
88
|
{
|
89
|
-
|
89
|
+
struct pollfd *p;
|
90
90
|
int res = poll (polls, pollcnt, (int)ceil (timeout * 1000.));
|
91
91
|
|
92
92
|
if (expect_false (res < 0))
|
@@ -97,20 +97,23 @@ poll_poll (EV_P_ ev_tstamp timeout)
|
|
97
97
|
fd_enomem (EV_A);
|
98
98
|
else if (errno != EINTR)
|
99
99
|
syserr ("(libev) poll");
|
100
|
-
|
101
|
-
return;
|
102
100
|
}
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
101
|
+
else
|
102
|
+
for (p = polls; res; ++p)
|
103
|
+
if (expect_false (p->revents)) /* this expect is debatable */
|
104
|
+
{
|
105
|
+
--res;
|
106
|
+
|
107
|
+
if (expect_false (p->revents & POLLNVAL))
|
108
|
+
fd_kill (EV_A_ p->fd);
|
109
|
+
else
|
110
|
+
fd_event (
|
111
|
+
EV_A_
|
112
|
+
p->fd,
|
113
|
+
(p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
|
114
|
+
| (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
|
115
|
+
);
|
116
|
+
}
|
114
117
|
}
|
115
118
|
|
116
119
|
int inline_size
|
data/libev/ev_port.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* libev solaris event port backend
|
3
3
|
*
|
4
|
-
* Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
|
4
|
+
* Copyright (c) 2007,2008 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-
|
data/libev/ev_select.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* libev select fd activity backend
|
3
3
|
*
|
4
|
-
* Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
|
4
|
+
* Copyright (c) 2007,2008 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-
|
@@ -54,12 +54,6 @@
|
|
54
54
|
#if EV_SELECT_IS_WINSOCKET
|
55
55
|
# undef EV_SELECT_USE_FD_SET
|
56
56
|
# define EV_SELECT_USE_FD_SET 1
|
57
|
-
# undef EINTR
|
58
|
-
# define EINTR WSAEINTR
|
59
|
-
# undef EBADF
|
60
|
-
# define EBADF WSAENOTSOCK
|
61
|
-
# undef ENOMEM
|
62
|
-
# define ENOMEM (errno + 1)
|
63
57
|
#endif
|
64
58
|
|
65
59
|
#if !EV_SELECT_USE_FD_SET
|
@@ -98,7 +92,7 @@ select_modify (EV_P_ int fd, int oev, int nev)
|
|
98
92
|
int word = fd / NFDBITS;
|
99
93
|
fd_mask mask = 1UL << (fd % NFDBITS);
|
100
94
|
|
101
|
-
if (expect_false (vec_max
|
95
|
+
if (expect_false (vec_max <= word))
|
102
96
|
{
|
103
97
|
int new_max = word + 1;
|
104
98
|
|
@@ -147,6 +141,29 @@ select_poll (EV_P_ ev_tstamp timeout)
|
|
147
141
|
#if EV_SELECT_IS_WINSOCKET
|
148
142
|
errno = WSAGetLastError ();
|
149
143
|
#endif
|
144
|
+
#ifdef WSABASEERR
|
145
|
+
/* on windows, select returns incompatible error codes, fix this */
|
146
|
+
if (errno >= WSABASEERR && errno < WSABASEERR + 1000)
|
147
|
+
if (errno == WSAENOTSOCK)
|
148
|
+
errno = EBADF;
|
149
|
+
else
|
150
|
+
errno -= WSABASEERR;
|
151
|
+
#endif
|
152
|
+
|
153
|
+
#ifdef _WIN32
|
154
|
+
/* select on windows errornously returns EINVAL when no fd sets have been
|
155
|
+
* provided (this is documented). what microsoft doesn't tell you that this bug
|
156
|
+
* exists even when the fd sets are provided, so we have to check for this bug
|
157
|
+
* here and emulate by sleeping manually.
|
158
|
+
* we also get EINVAL when the timeout is invalid, but we ignore this case here
|
159
|
+
* and assume that EINVAL always means: you have to wait manually.
|
160
|
+
*/
|
161
|
+
if (errno == EINVAL)
|
162
|
+
{
|
163
|
+
ev_sleep (timeout);
|
164
|
+
return;
|
165
|
+
}
|
166
|
+
#endif
|
150
167
|
|
151
168
|
if (errno == EBADF)
|
152
169
|
fd_ebadf (EV_A);
|
data/libev/ev_vars.h
CHANGED
@@ -55,6 +55,9 @@ VARx(ev_tstamp, backend_fudge) /* assumed typical timer resolution */
|
|
55
55
|
VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
|
56
56
|
VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout))
|
57
57
|
|
58
|
+
#if EV_USE_EVENTFD || EV_GENWRAP
|
59
|
+
VARx(int, evfd)
|
60
|
+
#endif
|
58
61
|
VAR (evpipe, int evpipe [2])
|
59
62
|
VARx(ev_io, pipeev)
|
60
63
|
|
@@ -109,12 +112,12 @@ VARx(int *, fdchanges)
|
|
109
112
|
VARx(int, fdchangemax)
|
110
113
|
VARx(int, fdchangecnt)
|
111
114
|
|
112
|
-
VARx(
|
115
|
+
VARx(ANHE *, timers)
|
113
116
|
VARx(int, timermax)
|
114
117
|
VARx(int, timercnt)
|
115
118
|
|
116
119
|
#if EV_PERIODIC_ENABLE || EV_GENWRAP
|
117
|
-
VARx(
|
120
|
+
VARx(ANHE *, periodics)
|
118
121
|
VARx(int, periodicmax)
|
119
122
|
VARx(int, periodiccnt)
|
120
123
|
#endif
|
data/libev/ev_win32.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* libev win32 compatibility cruft (_not_ a backend)
|
3
3
|
*
|
4
|
-
* Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
|
4
|
+
* Copyright (c) 2007,2008 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-
|
data/libev/ev_wrap.h
CHANGED
@@ -13,6 +13,7 @@
|
|
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 evfd ((loop)->evfd)
|
16
17
|
#define evpipe ((loop)->evpipe)
|
17
18
|
#define pipeev ((loop)->pipeev)
|
18
19
|
#define curpid ((loop)->curpid)
|
@@ -84,6 +85,7 @@
|
|
84
85
|
#undef backend_fudge
|
85
86
|
#undef backend_modify
|
86
87
|
#undef backend_poll
|
88
|
+
#undef evfd
|
87
89
|
#undef evpipe
|
88
90
|
#undef pipeev
|
89
91
|
#undef curpid
|
data/ruby_lib/ebb.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# See README file for details.
|
4
4
|
require 'stringio'
|
5
5
|
module Ebb
|
6
|
-
VERSION = "0.2.
|
6
|
+
VERSION = "0.2.1"
|
7
7
|
LIBDIR = File.dirname(__FILE__)
|
8
8
|
autoload :Runner, LIBDIR + '/ebb/runner'
|
9
9
|
autoload :FFI, LIBDIR + '/../src/ebb_ext'
|
@@ -18,7 +18,7 @@ module Ebb
|
|
18
18
|
FFI::server_listen_on_unix_socket(socketfile)
|
19
19
|
log.puts "Ebb is listening on unix socket #{socketfile}"
|
20
20
|
else
|
21
|
-
port = (options[:port] || 4001).to_i
|
21
|
+
port = (options[:Port] || options[:port] || 4001).to_i
|
22
22
|
FFI::server_listen_on_port(port)
|
23
23
|
log.puts "Ebb is listening at http://0.0.0.0:#{port}/"
|
24
24
|
end
|
@@ -30,10 +30,10 @@ module Ebb
|
|
30
30
|
while @running
|
31
31
|
FFI::server_process_connections()
|
32
32
|
while client = FFI::server_waiting_clients.shift
|
33
|
-
if app.respond_to?(:deferred?) and
|
34
|
-
process(app, client)
|
35
|
-
else
|
33
|
+
if app.respond_to?(:deferred?) and app.deferred?(client.env)
|
36
34
|
Thread.new(client) { |c| process(app, c) }
|
35
|
+
else
|
36
|
+
process(app, client)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -51,22 +51,34 @@ module Ebb
|
|
51
51
|
def self.process(app, client)
|
52
52
|
#p client.env
|
53
53
|
status, headers, body = app.call(client.env)
|
54
|
+
status = status.to_i
|
54
55
|
|
55
56
|
# Write the status
|
56
57
|
client.write_status(status)
|
57
58
|
|
58
59
|
# Add Content-Length to the headers.
|
59
|
-
if headers
|
60
|
-
headers.respond_to?(:[]=) and
|
61
|
-
body.respond_to?(:length) and
|
60
|
+
if !headers.has_key?('Content-Length') and
|
61
|
+
headers.respond_to?(:[]=) and
|
62
62
|
status != 304
|
63
63
|
then
|
64
|
-
|
64
|
+
# for String just use "length" method
|
65
|
+
if body.kind_of?(String)
|
66
|
+
headers['Content-Length'] = body.length.to_s
|
67
|
+
else
|
68
|
+
# for non-Array object call "each" and transform to Array
|
69
|
+
unless body.kind_of?(Array)
|
70
|
+
parts = []
|
71
|
+
body.each {|p| parts << p}
|
72
|
+
body = parts
|
73
|
+
end
|
74
|
+
# body is Array so calculate Content-Length as sum of length each part
|
75
|
+
headers['Content-Length'] = body.inject(0) {|s, p| s + p.length }.to_s
|
76
|
+
end
|
65
77
|
end
|
66
78
|
|
67
79
|
# Decide if we should keep the connection alive or not
|
68
|
-
|
69
|
-
if headers
|
80
|
+
unless headers.has_key?('Connection')
|
81
|
+
if headers.has_key?('Content-Length') and client.should_keep_alive?
|
70
82
|
headers['Connection'] = 'Keep-Alive'
|
71
83
|
else
|
72
84
|
headers['Connection'] = 'close'
|
@@ -103,6 +115,7 @@ module Ebb
|
|
103
115
|
BASE_ENV = {
|
104
116
|
'SERVER_NAME' => '0.0.0.0',
|
105
117
|
'SCRIPT_NAME' => '',
|
118
|
+
'QUERY_STRING' => '',
|
106
119
|
'SERVER_SOFTWARE' => "Ebb-Ruby #{Ebb::VERSION}",
|
107
120
|
'SERVER_PROTOCOL' => 'HTTP/1.1',
|
108
121
|
'rack.version' => [0, 1],
|
@@ -121,8 +134,7 @@ module Ebb
|
|
121
134
|
end
|
122
135
|
|
123
136
|
def write_status(status)
|
124
|
-
|
125
|
-
FFI::client_write_status(self, s, HTTP_STATUS_CODES[s])
|
137
|
+
FFI::client_write_status(self, status, HTTP_STATUS_CODES[status])
|
126
138
|
end
|
127
139
|
|
128
140
|
def write_body(data)
|
@@ -130,9 +142,7 @@ module Ebb
|
|
130
142
|
end
|
131
143
|
|
132
144
|
def write_header(field, value)
|
133
|
-
|
134
|
-
FFI::client_write_header(self, field, v.chomp)
|
135
|
-
end
|
145
|
+
FFI::client_write_header(self, field, value)
|
136
146
|
end
|
137
147
|
|
138
148
|
def release
|
@@ -144,12 +154,11 @@ module Ebb
|
|
144
154
|
end
|
145
155
|
|
146
156
|
def should_keep_alive?
|
147
|
-
if env['HTTP_VERSION'] == 'HTTP/1.0'
|
148
|
-
return
|
157
|
+
if env['HTTP_VERSION'] == 'HTTP/1.0'
|
158
|
+
return env['HTTP_CONNECTION'] =~ /Keep-Alive/i
|
149
159
|
else
|
150
|
-
return
|
160
|
+
return env['HTTP_CONNECTION'] !~ /close/i
|
151
161
|
end
|
152
|
-
false
|
153
162
|
end
|
154
163
|
end
|
155
164
|
|
@@ -183,6 +192,14 @@ module Ebb
|
|
183
192
|
def each(&block)
|
184
193
|
raise NotImplemented
|
185
194
|
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
# cause i don't want to create an array
|
199
|
+
def min(a,b)
|
200
|
+
a > b ? b : a
|
201
|
+
end
|
202
|
+
|
186
203
|
end
|
187
204
|
|
188
205
|
|
@@ -238,7 +255,3 @@ module Rack
|
|
238
255
|
end
|
239
256
|
end
|
240
257
|
|
241
|
-
# cause i don't want to create an array
|
242
|
-
def min(a,b)
|
243
|
-
a > b ? b : a
|
244
|
-
end
|