diff --git a/src/onion/log.c b/src/onion/log.c index 09dbc93..c1a31a3 100644 --- a/src/onion/log.c +++ b/src/onion/log.c @@ -186,7 +186,7 @@ void onion_log_stderr(onion_log_level level, const char *filename, int lineno, c if (!(onion_log_flags&OF_NOCOLOR)) strout_length+=sprintf(strout+strout_length, "\033[0m\n"); else - strout_length=sprintf(strout+strout_length, "\n"); + strout_length+=sprintf(strout+strout_length, "\n"); strout[strout_length]='\0'; // Use of write instead of fwrite, as it shoukd be atomic with kernel doing the diff --git a/src/onion/poller.c b/src/onion/poller.c index 357e6af..55ac37e 100644 --- a/src/onion/poller.c +++ b/src/onion/poller.c @@ -40,6 +40,7 @@ #include "types.h" #include "poller.h" #include "low.h" +#include #include #include #include @@ -90,6 +91,8 @@ struct onion_poller_slot_t{ onion_poller_slot *next; }; +#define MAX_SLOTS 1000000 + /** * @short Creates a new slot for the poller, for input data to be ready. * @memberof onion_poller_slot_t @@ -101,11 +104,26 @@ struct onion_poller_slot_t{ * @returns A new poller slot, ready to be added (onion_poller_add) or modified (onion_poller_slot_set_shutdown, onion_poller_slot_set_timeout). */ onion_poller_slot *onion_poller_slot_new(int fd, int (*f)(void*), void *data){ - if (fd<0){ + static onion_poller_slot empty_slot; + static onion_poller_slot *slots; + static rlim_t max_slots; + if (!max_slots) { + struct rlimit rlim; + if (getrlimit(RLIMIT_NOFILE, &rlim)) { + ONION_ERROR("getrlimit: %s", strerror(errno)); + return NULL; + } + max_slots = rlim.rlim_cur; + if (max_slots > MAX_SLOTS) + max_slots = MAX_SLOTS; + slots = (onion_poller_slot *)onion_low_calloc(max_slots, sizeof(onion_poller_slot)); + } + if (fd<0||fd>=max_slots){ ONION_ERROR("Trying to add an invalid file descriptor to the poller. Please check."); return NULL; } - onion_poller_slot *el=(onion_poller_slot*)onion_low_calloc(1, sizeof(onion_poller_slot)); + onion_poller_slot *el=&slots[fd]; + *el=empty_slot; el->fd=fd; el->f=f; el->data=data; @@ -121,9 +139,10 @@ onion_poller_slot *onion_poller_slot_new(int fd, int (*f)(void*), void *data){ * @memberof onion_poller_slot_t */ void onion_poller_slot_free(onion_poller_slot *el){ +/* Cannot zeroize the slot here because it's still needed for el->shutdown(), + * and it can be reused by another thread when ->shutdown() calls close(). */ if (el->shutdown) el->shutdown(el->shutdown_data); - onion_low_free(el); } /** @@ -332,6 +351,7 @@ onion_poller_slot *onion_poller_get(onion_poller *poller, int fd){ return NULL; } +#if 0 /** * @short Gets the next timeout * @@ -354,6 +374,7 @@ static int onion_poller_get_next_timeout(onion_poller *p){ //ONION_DEBUG("Next wakeup in %d ms, at least", timeout); return timeout; } +#endif // Max of events per loop. If not al consumed for next, so no prob. right number uses less memory, and makes less calls. static size_t onion_poller_max_events=1; @@ -378,8 +399,10 @@ void onion_poller_poll(onion_poller *p){ #else p->stop=0; #endif +#if 0 int maxtime; - time_t ctime; +#endif + time_t ctime, ptime = 0; int timeout; #ifdef HAVE_PTHREADS pthread_mutex_lock(&p->mutex); @@ -389,6 +412,7 @@ void onion_poller_poll(onion_poller *p){ char stop = !p->stop && p->head; #endif while (stop){ +#if 0 ctime=time(NULL); pthread_mutex_lock(&p->mutex); maxtime=onion_poller_get_next_timeout(p); @@ -399,20 +423,29 @@ void onion_poller_poll(onion_poller *p){ timeout=3600000; else timeout*=1000; +#else + timeout=1000; +#endif ONION_DEBUG0("Wait for %d ms", timeout); int nfds = epoll_wait(p->fd, event, onion_poller_max_events, timeout); +#if 0 int ctime_end=time(NULL); ONION_DEBUG0("Current time is %d, limit is %d, timeout is %d. Waited for %d seconds", ctime, maxtime, timeout, ctime_end-ctime); ctime=ctime_end; +#else + ctime = time(NULL); +#endif - pthread_mutex_lock(&p->mutex); - { // Somebody timedout? + if (ctime != ptime) { + ptime = ctime; + pthread_mutex_lock(&p->mutex); onion_poller_slot *next=p->head; while (next){ onion_poller_slot *cur=next; next=next->next; if (cur->timeout_limit <= ctime){ ONION_DEBUG0("Timeout on %d, was %d (ctime %d)", cur->fd, cur->timeout_limit, ctime); +#if 0 int i; for (i=0;itimeout_limit=INT_MAX; +#if 0 if (cur->shutdown){ cur->shutdown(cur->shutdown_data); onion_poller_slot_set_shutdown(cur,NULL,NULL); @@ -429,10 +464,13 @@ void onion_poller_poll(onion_poller *p){ // closed, do not even try to call it. cur->f=NULL; cur->data=NULL; +#else + shutdown(cur->fd, SHUT_RD); +#endif } } + pthread_mutex_unlock(&p->mutex); } - pthread_mutex_unlock(&p->mutex); if (nfds<0){ // This is normally closed p->fd //ONION_DEBUG("Some error happened"); // Also spurious wakeups... gdb is to blame sometimes or any other. @@ -466,12 +504,15 @@ void onion_poller_poll(onion_poller *p){ onion_low_free(bs); /* This cannot be onion_low_free since from backtrace_symbols. */ #endif +#if 0 /* Sometimes, el->f happens to be null. We want to remove this polling in that weird case. */ if (el->f) n= el->f(el->data); else n= -1; +#endif + n = el->f(el->data); ctime=time(NULL); if (el->timeout>0) diff --git a/src/onion/request.c b/src/onion/request.c index bde85aa..44e0585 100644 --- a/src/onion/request.c +++ b/src/onion/request.c @@ -55,10 +55,10 @@ void onion_request_parser_data_free(void *token); // At request_parser.c * They are in order of probability, with GET the most common. */ const char *onion_request_methods[16]={ - "GET", "POST", "HEAD", "OPTIONS", + "GET", "POST" /*, "HEAD", "OPTIONS", "PROPFIND", "PUT", "DELETE", "MOVE", "MKCOL", "PROPPATCH", "PATCH", NULL, - NULL, NULL, NULL, NULL }; + NULL, NULL, NULL, NULL*/ }; /** * @short Creates a request object diff --git a/src/onion/response.c b/src/onion/response.c index 5a22de0..74a2851 100644 --- a/src/onion/response.c +++ b/src/onion/response.c @@ -130,8 +130,6 @@ onion_response *onion_response_new(onion_request *req){ pthread_rwlock_unlock(&onion_response_date_lock); #endif #endif // USE_DATE_HEADER - // Sorry for the advertisment. - onion_dict_add(res->headers, "Server", "libonion v" ONION_VERSION " - coralbits.com", 0); onion_dict_add(res->headers, "Content-Type", "text/html", 0); // Maybe not the best guess, but really useful. //time_t t=time(NULL); //onion_dict_add(res->headers, "Date", asctime(localtime(&t)), OD_DUP_VALUE);