{
struct worker* worker = (struct worker*)arg;
int num = worker->thread_num;
+ log_thread_set(&worker->thread_num);
ub_thread_blocksigs();
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
/* close pipe ends used by main */
/* before stopping main worker, handle signals ourselves, so we
don't die on multiple reload signals for example. */
signal_handling_record();
+ log_thread_set(NULL);
for(i=0; i<daemon->num; i++)
worker_delete(daemon->workers[i]);
free(daemon->workers);
+2 March 2007: Wouter
+ - do not compile fork funcs unless needed. Otherwise will give
+ type errors as their typedefs have not been enabled.
+ - log shows thread numbers much more nicely (and portably).
+
1 March 2007: Wouter
- Signals, libevent and threads work well, with libevent patch and
changes to code (close after event_del).
TODO items.
o use real entropy to make random (ID, port) numbers more random.
+o in production mode, do not free memory on exit. In debug mode, test leaks.
#endif /* HAVE_PTHREAD */
}
+#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
/**
* No threading available: fork a new process.
* This means no shared data structure, and no locking.
log_warn("process %d abnormal exit with status %d",
(int)thread, status);
}
+#endif /* !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS) */
+
+#ifdef HAVE_SOLARIS_THREADS
+void* ub_thread_key_get(ub_thread_key_t key)
+{
+ void* ret=NULL;
+ LOCKRET(thr_getspecific(key, &ret));
+ return ret;
+}
+#endif
#define ub_thread_self() pthread_self()
/** wait for another thread to terminate */
#define ub_thread_join(thread) LOCKRET(pthread_join(thread, NULL))
+typedef pthread_key_t ub_thread_key_t;
+#define ub_thread_key_create(key, f) LOCKRET(pthread_key_create(key, f))
+#define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v))
+#define ub_thread_key_get(key) pthread_getspecific(key)
#else /* we do not HAVE_PTHREAD */
#ifdef HAVE_SOLARIS_THREADS
#define ub_thread_create(thr, func, arg) LOCKRET(thr_create(NULL, NULL, func, arg, NULL, thr))
#define ub_thread_self() thr_self()
#define ub_thread_join(thread) LOCKRET(thr_join(thread, NULL, NULL))
+typedef thread_key_t ub_thread_key_t;
+#define ub_thread_key_create(key, f) LOCKRET(thr_keycreate(key, f))
+#define ub_thread_key_set(key, v) LOCKRET(thr_setspecific(key, v))
+void* ub_thread_key_get(ub_thread_key_t key);
#else /* we do not HAVE_SOLARIS_THREADS and no PTHREADS */
#define ub_thread_join(thread) ub_thr_fork_wait(thread)
void ub_thr_fork_wait(ub_thread_t thread);
void ub_thr_fork_create(ub_thread_t* thr, void* (*func)(void*), void* arg);
+typedef void* ub_thread_key_t;
+#define ub_thread_key_create(key, f) (*(key)) = NULL
+#define ub_thread_key_set(key, v) (key) = (v)
+#define ub_thread_key_get(key) (key)
#endif /* HAVE_SOLARIS_THREADS */
#endif /* HAVE_PTHREAD */
enum verbosity_value verbosity = 0;
/** the file logged to. */
static FILE* logfile = 0;
+/** if key has been created */
+static int key_created = 0;
+/** pthread key for thread ids in logfile */
+static ub_thread_key_t logkey;
void
log_init(const char* filename)
{
FILE *f;
+ if(!key_created) {
+ key_created = 1;
+ ub_thread_key_create(&logkey, NULL);
+ }
+
if(!filename || !filename[0]) {
if(logfile && logfile != stderr)
fclose(logfile);
logfile = f;
}
+void log_thread_set(int* num)
+{
+ ub_thread_key_set(logkey, num);
+}
+
void
log_vmsg(const char* type, const char *format, va_list args)
{
char message[MAXSYSLOGMSGLEN];
const char* ident="unbound";
+ unsigned int* tid = (unsigned int*)ub_thread_key_get(logkey);
vsnprintf(message, sizeof(message), format, args);
fprintf(logfile, "[%d] %s[%d:%x] %s: %s\n",
(int)time(NULL), ident, (int)getpid(),
- (unsigned int)ub_thread_self(),
- type, message);
+ tid?*tid:0, type, message);
fflush(logfile);
}
*/
void log_init(const char* filename);
+/**
+ * Init a thread (will print this number for the thread log entries).
+ * Must be called from the thread itself. If not called 0 is printed.
+ * @param num: number to print for this thread. Owned by caller, must
+ * continue to exist.
+ */
+void log_thread_set(int* num);
+
/**
* Log informational message.
* Pass printf formatted arguments. No trailing newline is needed.