19
19
20
20
#include "sockhub.h"
21
21
22
+ #define SOCKHUB_BUFFER_SIZE (1024*1024)
23
+ #define ERR_BUF_SIZE 1024
24
+
25
+ void ShubAddSocket (Shub * shub , int fd );
26
+
27
+ inline void ShubAddSocket (Shub * shub , int fd )
28
+ {
29
+ #ifdef USE_EPOLL
30
+ struct epoll_event ev ;
31
+ ev .events = EPOLLIN ;
32
+ ev .data .fd = fd ;
33
+ if (epoll_ctl (shub -> epollfd , EPOLL_CTL_ADD , fd , & ev ) < 0 ) {
34
+ char buf [ERR_BUF_SIZE ];
35
+ sprintf (buf , "Failed to add socket %d to epoll set" , fd );
36
+ shub -> params -> error_handler (buf , SHUB_FATAL_ERROR );
37
+ }
38
+ #else
39
+ FD_SET (fd , & shub -> inset );
40
+ if (fd > shub -> max_fd ) {
41
+ shub -> max_fd = fd ;
42
+ }
43
+ #endif
44
+ }
45
+
46
+
22
47
static void default_error_handler (char const * msg , ShubErrorSeverity severity )
23
48
{
24
49
perror (msg );
@@ -116,8 +141,15 @@ static int resolve_host_by_name(const char *hostname, unsigned* addrs, unsigned*
116
141
117
142
static void close_socket (Shub * shub , int fd )
118
143
{
119
- close (fd );
144
+ #ifdef USE_EPOLL
145
+ if (epoll_ctl (shub -> epollfd , EPOLL_CTL_DEL , fd , NULL ) < 0 ) {
146
+ char buf [ERR_BUF_SIZE ];
147
+ sprintf (buf , "Failed to remove socket %d from epoll set" , fd );
148
+ shub -> params -> error_handler (buf , SHUB_RECOVERABLE_ERROR );
149
+ }
150
+ #else
120
151
FD_CLR (fd , & shub -> inset );
152
+ #endif
121
153
}
122
154
123
155
int ShubReadSocketEx (int sd , void * buf , int min_size , int max_size )
@@ -211,7 +243,12 @@ static void reconnect(Shub* shub)
211
243
} else {
212
244
int optval = 1 ;
213
245
setsockopt (shub -> output , IPPROTO_TCP , TCP_NODELAY , (char const * )& optval , sizeof (optval ));
214
- FD_SET (shub -> output , & shub -> inset );
246
+ optval = SOCKHUB_BUFFER_SIZE ;
247
+ setsockopt (shub -> output , SOL_SOCKET , SO_SNDBUF , (const char * ) & optval , sizeof (int ));
248
+ optval = SOCKHUB_BUFFER_SIZE ;
249
+ setsockopt (shub -> output , SOL_SOCKET , SO_RCVBUF , (const char * ) & optval , sizeof (int ));
250
+
251
+ ShubAddSocket (shub , shub -> output );
215
252
return ;
216
253
}
217
254
}
@@ -238,6 +275,7 @@ static void notify_disconnect(Shub* shub, int chan)
238
275
239
276
static void recovery (Shub * shub )
240
277
{
278
+ #ifndef USE_EPOLL
241
279
int i , max_fd ;
242
280
243
281
for (i = 0 , max_fd = shub -> max_fd ; i <= max_fd ; i ++ ) {
@@ -254,6 +292,7 @@ static void recovery(Shub* shub)
254
292
}
255
293
}
256
294
}
295
+ #endif
257
296
}
258
297
259
298
void ShubInitialize (Shub * shub , ShubParams * params )
@@ -276,11 +315,17 @@ void ShubInitialize(Shub* shub, ShubParams* params)
276
315
if (listen (shub -> input , params -> queue_size ) < 0 ) {
277
316
shub -> params -> error_handler ("Failed to listen local socket" , SHUB_FATAL_ERROR );
278
317
}
279
- FD_ZERO (& shub -> inset );
280
- FD_SET (shub -> input , & shub -> inset );
281
-
282
318
shub -> output = -1 ;
283
- shub -> max_fd = shub -> input ;
319
+ #ifdef USE_EPOLL
320
+ shub -> epollfd = epoll_create (MAX_EVENTS );
321
+ if (shub -> epollfd < 0 ) {
322
+ shub -> params -> error_handler ("Failed to create epoll" , SHUB_FATAL_ERROR );
323
+ }
324
+ #else
325
+ FD_ZERO (& shub -> inset );
326
+ shub -> max_fd = 0 ;
327
+ #endif
328
+ ShubAddSocket (shub , shub -> input );
284
329
reconnect (shub );
285
330
286
331
shub -> in_buffer = malloc (params -> buffer_size );
@@ -301,43 +346,61 @@ static void die(int sig)
301
346
void ShubLoop (Shub * shub )
302
347
{
303
348
int buffer_size = shub -> params -> buffer_size ;
349
+ sigset_t sset ;
304
350
signal (SIGINT , die );
305
351
signal (SIGQUIT , die );
306
352
signal (SIGTERM , die );
307
- // signal(SIGHUP, die);
308
- sigset_t sset ;
353
+ /* signal(SIGHUP, die); */
309
354
sigfillset (& sset );
310
355
sigprocmask (SIG_UNBLOCK , & sset , NULL );
311
356
312
- while (!stop ) {
357
+ while (!stop ) {
358
+ int i , rc ;
359
+ #ifdef USE_EPOLL
360
+ struct epoll_event events [MAX_EVENTS ];
361
+ rc = epoll_wait (shub -> epollfd , events , MAX_EVENTS , shub -> in_buffer_used == 0 ? -1 : shub -> params -> delay );
362
+ #else
313
363
fd_set events ;
314
364
struct timeval tm ;
315
- int i , rc ;
316
365
int max_fd = shub -> max_fd ;
317
366
318
367
tm .tv_sec = shub -> params -> delay /1000 ;
319
368
tm .tv_usec = shub -> params -> delay % 1000 * 1000 ;
320
-
321
369
events = shub -> inset ;
322
370
rc = select (max_fd + 1 , & events , NULL , NULL , shub -> in_buffer_used == 0 ? NULL : & tm );
323
- if (rc < 0 ) {
324
- if (errno != EINTR ) {
371
+ #endif
372
+ if (rc < 0 ) {
373
+ if (errno != EINTR ) {
325
374
shub -> params -> error_handler ("Select failed" , SHUB_RECOVERABLE_ERROR );
326
375
recovery (shub );
327
376
}
328
377
} else {
329
378
if (rc > 0 ) {
379
+ #ifdef USE_EPOLL
380
+ int j ;
381
+ int n = rc ;
382
+ for (j = 0 ; j < n ; j ++ ) {
383
+ i = events [j ].data .fd ;
384
+ if (events [j ].events & EPOLLERR ) {
385
+ if (i == shub -> input ) {
386
+ shub -> params -> error_handler ("Input socket error" , SHUB_FATAL_ERROR );
387
+ } else if (i == shub -> output ) {
388
+ reconnect (shub );
389
+ } else {
390
+ notify_disconnect (shub , i );
391
+ close_socket (shub , i );
392
+ }
393
+ } else if (events [j ].events & EPOLLIN ) {
394
+ #else
330
395
for (i = 0 ; i <= max_fd ; i ++ ) {
331
396
if (FD_ISSET (i , & events )) {
332
- if (i == shub -> input ) { /* accept incomming connection */
397
+ #endif
398
+ if (i == shub -> input ) { /* accept incomming connection */
333
399
int s = accept (i , NULL , NULL );
334
400
if (s < 0 ) {
335
401
shub -> params -> error_handler ("Failed to accept socket" , SHUB_RECOVERABLE_ERROR );
336
402
} else {
337
- if (s > shub -> max_fd ) {
338
- shub -> max_fd = s ;
339
- }
340
- FD_SET (s , & shub -> inset );
403
+ ShubAddSocket (shub , s );
341
404
}
342
405
} else if (i == shub -> output ) { /* receive response from server */
343
406
/* try to read as much as possible */
@@ -424,8 +487,11 @@ void ShubLoop(Shub* shub)
424
487
assert (sizeof (ShubMessageHdr ) > available );
425
488
/* read as much as possible */
426
489
rc = ShubReadSocketEx (chan , & shub -> in_buffer [pos + available ], sizeof (ShubMessageHdr ) - available , buffer_size - pos - available );
427
- if (rc < sizeof (ShubMessageHdr ) - available ) {
428
- shub -> params -> error_handler ("Failed to read local socket" , SHUB_RECOVERABLE_ERROR );
490
+ if (rc < sizeof (ShubMessageHdr ) - available ) {
491
+ char buf [ERR_BUF_SIZE ];
492
+ sprintf (buf , "Failed to read local socket chan=%d, rc=%d, min requested=%ld, max requested=%d, errno=%d" , chan , rc , sizeof (ShubMessageHdr ) - available , buffer_size - pos - available , errno );
493
+ shub -> params -> error_handler (buf , SHUB_RECOVERABLE_ERROR );
494
+ //shub->params->error_handler("Failed to read local socket", SHUB_RECOVERABLE_ERROR);
429
495
close_socket (shub , i );
430
496
shub -> in_buffer_used = pos ;
431
497
notify_disconnect (shub , i );
@@ -460,8 +526,11 @@ void ShubLoop(Shub* shub)
460
526
/* fetch rest of message body */
461
527
do {
462
528
unsigned int n = processed + size > buffer_size ? buffer_size - processed : size ;
463
- if (chan >= 0 && !ShubReadSocket (chan , shub -> in_buffer + processed , n )) {
464
- shub -> params -> error_handler ("Failed to read local socket" , SHUB_RECOVERABLE_ERROR );
529
+ if (chan >= 0 && !ShubReadSocket (chan , shub -> in_buffer + processed , n )) {
530
+ char buf [ERR_BUF_SIZE ];
531
+ sprintf (buf , "Failed to read local socket rc=%d, len=%d, errno=%d" , rc , n , errno );
532
+ shub -> params -> error_handler (buf , SHUB_RECOVERABLE_ERROR );
533
+ //shub->params->error_handler("Failed to read local socket", SHUB_RECOVERABLE_ERROR);
465
534
close_socket (shub , chan );
466
535
if (hdr != NULL ) { /* if message header is not yet sent to the server... */
467
536
/* ... then skip this message */
0 commit comments