diff options
author | Stefan Metzmacher <metze@samba.org> | 2005-01-14 01:32:56 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:08:49 -0500 |
commit | 9327ec51d11855ec0ceac3ce1f4e0a75c8b57081 (patch) | |
tree | 7f4427b4246b91b050c16e8dc5d1f0433eb7cc2d /source4/smbd/process_thread.c | |
parent | cfc10f2a83b7c6190742498f1027256215cd0b31 (diff) | |
download | samba-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.c | 136 |
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; |