summaryrefslogtreecommitdiff
path: root/source4/smbd/process_thread.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-01-14 01:32:56 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:08:49 -0500
commit9327ec51d11855ec0ceac3ce1f4e0a75c8b57081 (patch)
tree7f4427b4246b91b050c16e8dc5d1f0433eb7cc2d /source4/smbd/process_thread.c
parentcfc10f2a83b7c6190742498f1027256215cd0b31 (diff)
downloadsamba-9327ec51d11855ec0ceac3ce1f4e0a75c8b57081.tar.gz
samba-9327ec51d11855ec0ceac3ce1f4e0a75c8b57081.tar.bz2
samba-9327ec51d11855ec0ceac3ce1f4e0a75c8b57081.zip
r4728: split up server_services into:
- stream_socket services the smb, ldap and rpc service which sets up a srtam socket end then waits for connections and - task services which this you can create a seperate task that do something (this is also going through the process_model subsystem so with -M standard a new process for this created with -M thread a new thread ... I'll add datagram services later when we whave support for datagram sockets in lib/socket/ see the next commit as an example for service_task's metze (This used to be commit d5fa02746c6569b09b6e05785642da2fad3ba3e0)
Diffstat (limited to 'source4/smbd/process_thread.c')
-rw-r--r--source4/smbd/process_thread.c136
1 files changed, 96 insertions, 40 deletions
diff --git a/source4/smbd/process_thread.c b/source4/smbd/process_thread.c
index 8e8ee23aaf..f0e98221ae 100644
--- a/source4/smbd/process_thread.c
+++ b/source4/smbd/process_thread.c
@@ -33,9 +33,12 @@
static void *thread_connection_fn(void *thread_parm)
{
- struct event_context *ev = thread_parm;
+ struct server_connection *conn = thread_parm;
+
+ conn->connection.id = pthread_self();
+
/* wait for action */
- event_loop_wait(ev);
+ event_loop_wait(conn->event.ctx);
#if 0
pthread_cleanup_pop(1); /* will invoke terminate_mt_connection() */
@@ -43,11 +46,6 @@ static void *thread_connection_fn(void *thread_parm)
return NULL;
}
-static int thread_get_id(struct smbsrv_request *req)
-{
- return (int)pthread_self();
-}
-
/*
called when a listening socket becomes readable
*/
@@ -59,15 +57,15 @@ static void thread_accept_connection(struct event_context *ev, struct fd_event *
int rc;
pthread_t thread_id;
pthread_attr_t thread_attr;
- struct server_socket *server_socket = srv_fde->private;
+ struct server_stream_socket *stream_socket = srv_fde->private;
struct server_connection *conn;
/* accept an incoming connection. */
- status = socket_accept(server_socket->socket, &sock);
+ status = socket_accept(stream_socket->socket, &sock);
if (!NT_STATUS_IS_OK(status)) {
return;
}
-
+
/* create new detached thread for this connection. The new
thread gets a new event_context with a single fd_event for
receiving from the new socket. We set that thread running
@@ -75,13 +73,13 @@ static void thread_accept_connection(struct event_context *ev, struct fd_event *
main event_context is continued.
*/
- ev = event_context_init(server_socket);
+ ev = event_context_init(stream_socket);
if (!ev) {
socket_destroy(sock);
- return;
+ return;
}
- conn = server_setup_connection(ev, server_socket, sock, t, pthread_self());
+ conn = server_setup_connection(ev, stream_socket, sock, t, -1);
if (!conn) {
event_context_destroy(ev);
socket_destroy(sock);
@@ -91,16 +89,9 @@ static void thread_accept_connection(struct event_context *ev, struct fd_event *
talloc_steal(conn, ev);
talloc_steal(conn, sock);
- /* TODO: is this MUTEX_LOCK in the right place here?
- * --metze
- */
- MUTEX_LOCK_BY_ID(MUTEX_SMBD);
- DLIST_ADD(server_socket->connection_list,conn);
- MUTEX_UNLOCK_BY_ID(MUTEX_SMBD);
-
pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
- rc = pthread_create(&thread_id, &thread_attr, thread_connection_fn, ev);
+ rc = pthread_create(&thread_id, &thread_attr, thread_connection_fn, conn);
pthread_attr_destroy(&thread_attr);
if (rc == 0) {
DEBUG(4,("accept_connection_thread: created thread_id=%lu for fd=%d\n",
@@ -414,7 +405,7 @@ static void thread_fault_handler(int sig)
/*
called when the process model is selected
*/
-static void thread_model_startup(void)
+static void thread_model_init(struct server_context *server)
{
struct mutex_ops m_ops;
struct debug_ops d_ops;
@@ -422,8 +413,6 @@ static void thread_model_startup(void)
ZERO_STRUCT(m_ops);
ZERO_STRUCT(d_ops);
- smbd_process_init();
-
/* register mutex/rwlock handlers */
m_ops.mutex_init = thread_mutex_init;
m_ops.mutex_lock = thread_mutex_lock;
@@ -448,33 +437,100 @@ static void thread_model_startup(void)
register_debug_handlers("thread", &d_ops);
}
-static void thread_exit_server(struct server_context *srv_ctx, const char *reason)
+static void thread_model_exit(struct server_context *server, const char *reason)
{
- DEBUG(1,("thread_exit_server: reason[%s]\n",reason));
+ DEBUG(1,("thread_model_exit: reason[%s]\n",reason));
+ talloc_free(server);
+ exit(0);
}
+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
+};
+
/*
initialise the thread process model, registering ourselves with the model subsystem
*/
NTSTATUS process_model_thread_init(void)
{
NTSTATUS ret;
- struct model_ops ops;
-
- ZERO_STRUCT(ops);
-
- /* fill in our name */
- ops.name = "thread";
-
- /* fill in all the operations */
- ops.model_startup = thread_model_startup;
- ops.accept_connection = thread_accept_connection;
- ops.terminate_connection = thread_terminate_connection;
- ops.exit_server = thread_exit_server;
- ops.get_id = thread_get_id;
/* register ourselves with the PROCESS_MODEL subsystem. */
- ret = register_process_model(&ops);
+ ret = register_process_model(&thread_ops);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(0,("Failed to register process_model 'thread'!\n"));
return ret;