#include <limits.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
#include <netdb.h>
#include <sys/un.h>
#include <string.h>
static int num_threads = 0; /* Current number of threads */
int num_sessions = 0; /* Current number of sessions */
-pthread_t initial_thread; /* tid for main() thread */
-
int syslog_facility = (-1);
}
else if (loglevel <= verbosity) {
struct timeval tv;
- struct tm *tim;
+ struct tm tim;
time_t unixtime;
gettimeofday(&tv, NULL);
/* Promote to time_t; types differ on some OSes (like darwin) */
unixtime = tv.tv_sec;
- tim = localtime(&unixtime);
+ localtime_r(&unixtime, &tim);
/*
* Log provides millisecond accuracy. If you need
* microsecond accuracy and your OS supports it, change
/* Millisecond display */
fprintf(stderr,
"%04d/%02d/%02d %2d:%02d:%02d.%03ld [%3d] %s",
- tim->tm_year + 1900, tim->tm_mon + 1,
- tim->tm_mday, tim->tm_hour, tim->tm_min,
- tim->tm_sec, (long)tv.tv_usec / 1000,
+ tim.tm_year + 1900, tim.tm_mon + 1,
+ tim.tm_mday, tim.tm_hour, tim.tm_min,
+ tim.tm_sec, (long)tv.tv_usec / 1000,
CC->cs_pid, buf);
#endif
/* Microsecond display */
fprintf(stderr,
"%04d/%02d/%02d %2d:%02d:%02d.%06ld [%3d] %s",
- tim->tm_year + 1900, tim->tm_mon + 1,
- tim->tm_mday, tim->tm_hour, tim->tm_min,
- tim->tm_sec, (long)tv.tv_usec,
+ tim.tm_year + 1900, tim.tm_mon + 1,
+ tim.tm_mday, tim.tm_hour, tim.tm_min,
+ tim.tm_sec, (long)tv.tv_usec,
CC->cs_pid, buf);
} else {
#if 0
/* Millisecond display */
fprintf(stderr,
"%04d/%02d/%02d %2d:%02d:%02d.%03ld %s",
- tim->tm_year + 1900, tim->tm_mon + 1,
- tim->tm_mday, tim->tm_hour, tim->tm_min,
- tim->tm_sec, (long)tv.tv_usec / 1000, buf);
+ tim.tm_year + 1900, tim.tm_mon + 1,
+ tim.tm_mday, tim.tm_hour, tim.tm_min,
+ tim.tm_sec, (long)tv.tv_usec / 1000, buf);
#endif
/* Microsecond display */
fprintf(stderr,
"%04d/%02d/%02d %2d:%02d:%02d.%06ld %s",
- tim->tm_year + 1900, tim->tm_mon + 1,
- tim->tm_mday, tim->tm_hour, tim->tm_min,
- tim->tm_sec, (long)tv.tv_usec, buf);
+ tim.tm_year + 1900, tim.tm_mon + 1,
+ tim.tm_mday, tim.tm_hour, tim.tm_min,
+ tim.tm_sec, (long)tv.tv_usec, buf);
}
fflush(stderr);
}
* called this function. If there's no such binding (for example, if it's
* called by the housekeeper thread) then a generic 'master' CC is returned.
*
- * It's inlined because it's used *VERY* frequently.
+ * This function is used *VERY* frequently and must be kept small.
*/
-INLINE struct CitContext *MyContext(void) {
- return ((pthread_getspecific(MyConKey) == NULL)
- ? &masterCC
- : (struct CitContext *) pthread_getspecific(MyConKey)
+struct CitContext *MyContext(void) {
+
+ register struct CitContext *c;
+
+ return ((c = (struct CitContext *) pthread_getspecific(MyConKey),
+ c == NULL) ? &masterCC : c
);
}
*/
void unbuffer_output(void) {
if (CC->buffering == 1) {
- flush_output();
CC->buffering = 0;
+ /* We don't call flush_output because we can't. */
+ client_write(CC->output_buffer, CC->buffer_len);
+ CC->buffer_len = 0;
free(CC->output_buffer);
CC->output_buffer = NULL;
}
if ((ret = pthread_attr_setstacksize(&attr, 128 * 1024))) {
lprintf(CTDL_EMERG, "pthread_attr_setstacksize: %s\n", strerror(ret));
time_to_die = -1;
+ pthread_attr_destroy(&attr);
return;
}
n->next = worker_list;
worker_list = n;
+ pthread_attr_destroy(&attr);
}
struct CitContext *ptr;
struct CitContext *bind_me = NULL;
fd_set readfds;
- int retval;
+ int retval = 0;
struct CitContext *con= NULL; /* Temporary context pointer */
struct ServiceFunctionHook *serviceptr;
int ssock; /* Descriptor for client socket */
tv.tv_usec = 0;
retval = select(highest + 1, &readfds, NULL, NULL, &tv);
}
- else {
- break;
- }
+
+ if (time_to_die) return(NULL);
/* Now figure out who made this select() unblock.
* First, check for an error or exit condition.
}
}
- if (time_to_die) {
- break;
- }
-
/* It must be a client socket. Find a context that has data
* waiting on its socket *and* is in the CON_IDLE state. Any
* active sockets other than our chosen one are marked as
}
/* If control reaches this point, the server is shutting down */
- --num_threads;
- return NULL;
+ return(NULL);
}