+static void *thread_task_fn(void *thread_parm)
+{
+ struct server_task *task = thread_parm;
+
+ task->task.id = pthread_self();
+
+ task->event.ctx = event_context_init(task);
+ if (!task->event.ctx) {
+ server_terminate_task(task, "event_context_init() failed");
+ return NULL;
+ }
+
+ task->messaging.ctx = messaging_init(task, task->task.id, task->event.ctx);
+ if (!task->messaging.ctx) {
+ server_terminate_task(task, "messaging_init() failed");
+ return NULL;
+ }
+
+ task->task.ops->task_init(task);
+
+ /* wait for action */
+ event_loop_wait(task->event.ctx);
+
+ server_terminate_task(task, "exit");
+#if 0
+ pthread_cleanup_pop(1); /* will invoke terminate_mt_connection() */
+#endif
+ return NULL;
+}
+/*
+ called to create a new event context for a new task
+*/
+static void thread_create_task(struct server_task *task)
+{
+ int rc;
+ pthread_t thread_id;
+ pthread_attr_t thread_attr;
+
+ pthread_attr_init(&thread_attr);
+ pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
+ rc = pthread_create(&thread_id, &thread_attr, thread_task_fn, task);
+ pthread_attr_destroy(&thread_attr);
+ if (rc == 0) {
+ DEBUG(4,("thread_create_task: created thread_id=%lu for task='%s'\n",
+ (unsigned long int)thread_id, task->task.ops->name));
+ } else {
+ DEBUG(0,("thread_create_task: thread create failed for task='%s', rc=%d\n", task->task.ops->name, rc));
+ return;
+ }
+ return;
+}
+
+/*
+ called to destroy a new event context for a new task
+*/
+static void thread_terminate_task(struct server_task *task, const char *reason)
+{
+ DEBUG(2,("thread_terminate_task: reason[%s]\n",reason));
+
+ talloc_free(task);
+
+ /* terminate this thread */
+ pthread_exit(NULL); /* thread cleanup routine will do actual cleanup */
+}
+
+static const struct model_ops thread_ops = {
+ .name = "thread",
+
+ .model_init = thread_model_init,
+ .model_exit = thread_model_exit,
+
+ .accept_connection = thread_accept_connection,
+ .terminate_connection = thread_terminate_connection,
+
+ .create_task = thread_create_task,
+ .terminate_task = thread_terminate_task
+};
+