diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-01-30 00:54:57 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:09:22 -0500 |
commit | 55d4d36993293fee914a009f1d8f05810e347f2b (patch) | |
tree | 587a9bafd1c8df901aad8766acb0fe9ef4c3d8c0 /source4/smbd/process_thread.c | |
parent | 5540449f1cd9d9a6efab59f2bf47be4e1487ffc2 (diff) | |
download | samba-55d4d36993293fee914a009f1d8f05810e347f2b.tar.gz samba-55d4d36993293fee914a009f1d8f05810e347f2b.tar.bz2 samba-55d4d36993293fee914a009f1d8f05810e347f2b.zip |
r5102: This is a major simplification of the logic for controlling top level
servers in smbd. The old code still contained a fairly bit of legacy
from the time when smbd was only handling SMB connection. The new code
gets rid of all of the smb_server specific code in smbd/, and creates
a much simpler infrastructures for new server code.
Major changes include:
- simplified the process model code a lot.
- got rid of the top level server and service structures
completely. The top level context is now the event_context. This
got rid of service.h and server.h completely (they were the most
confusing parts of the old code)
- added service_stream.[ch] for the helper functions that are
specific to stream type services (services that handle streams, and
use a logically separate process per connection)
- got rid of the builtin idle_handler code in the service logic, as
none of the servers were using it, and it can easily be handled by
a server in future by adding its own timed_event to the event
context.
- fixed some major memory leaks in the rpc server code.
- added registration of servers, rather than hard coding our list of
possible servers. This allows for servers as modules in the future.
- temporarily disabled the winbind code until I add the helper
functions for that type of server
- added error checking on service startup. If a configured server
fails to startup then smbd doesn't startup.
- cleaned up the command line handling in smbd, removing unused options
(This used to be commit cf6a46c3cbde7b1eb1b86bd3882b953a2de3a42e)
Diffstat (limited to 'source4/smbd/process_thread.c')
-rw-r--r-- | source4/smbd/process_thread.c | 164 |
1 files changed, 43 insertions, 121 deletions
diff --git a/source4/smbd/process_thread.c b/source4/smbd/process_thread.c index 8d65292cfd..6b62ca413e 100644 --- a/source4/smbd/process_thread.c +++ b/source4/smbd/process_thread.c @@ -1,7 +1,9 @@ /* Unix SMB/CIFS implementation. + thread model: standard (1 thread per client connection) - Copyright (C) Andrew Tridgell 2003 + + Copyright (C) Andrew Tridgell 2003-2005 Copyright (C) James J Myers 2003 <myersjj@samba.org> Copyright (C) Stefan (metze) Metzmacher 2004 @@ -30,89 +32,85 @@ #include "events.h" #include "dlinklist.h" #include "smb_server/smb_server.h" -#include "process_model.h" + +struct new_conn_state { + struct event_context *ev; + struct socket_context *sock; + void (*new_conn)(struct event_context *, struct socket_context *, uint32_t , void *); + void *private; +}; static void *thread_connection_fn(void *thread_parm) { - struct server_connection *conn = thread_parm; + struct new_conn_state *new_conn = talloc_get_type(thread_parm, struct new_conn_state); - conn->connection.id = pthread_self(); + new_conn->new_conn(new_conn->ev, new_conn->sock, pthread_self(), new_conn->private); - /* wait for action */ - event_loop_wait(conn->event.ctx); + /* run this connection from here */ + event_loop_wait(new_conn->ev); + + talloc_free(new_conn); -#if 0 - pthread_cleanup_pop(1); /* will invoke terminate_mt_connection() */ -#endif return NULL; } /* called when a listening socket becomes readable */ -static void thread_accept_connection(struct event_context *ev, struct fd_event *srv_fde, - struct timeval t, uint16_t flags) +static void thread_accept_connection(struct event_context *ev, + struct socket_context *sock, + void (*new_conn)(struct event_context *, struct socket_context *, + uint32_t , void *), + void *private) { NTSTATUS status; - struct socket_context *sock; int rc; pthread_t thread_id; pthread_attr_t thread_attr; - struct server_stream_socket *stream_socket = srv_fde->private; - struct server_connection *conn; + struct new_conn_state *state; + struct event_context *ev2; - /* accept an incoming connection. */ - status = socket_accept(stream_socket->socket, &sock); - if (!NT_STATUS_IS_OK(status)) { - return; - } + ev2 = event_context_init(ev); + if (ev2 == NULL) 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 - with the main event loop, then return. When we return the - main event_context is continued. - */ - - ev = event_context_init(stream_socket); - if (!ev) { - socket_destroy(sock); + state = talloc(ev2, struct new_conn_state); + if (state == NULL) { + talloc_free(ev2); return; } - conn = server_setup_connection(ev, stream_socket, sock, t, -1); - if (!conn) { - event_context_destroy(ev); - socket_destroy(sock); + state->new_conn = new_conn; + state->private = private; + state->ev = ev2; + + /* accept an incoming connection. */ + status = socket_accept(sock, &state->sock); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ev2); return; } - talloc_steal(conn, ev); - talloc_steal(conn, sock); + talloc_steal(state, state->sock); pthread_attr_init(&thread_attr); pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); - rc = pthread_create(&thread_id, &thread_attr, thread_connection_fn, conn); + rc = pthread_create(&thread_id, &thread_attr, thread_connection_fn, state); pthread_attr_destroy(&thread_attr); if (rc == 0) { DEBUG(4,("accept_connection_thread: created thread_id=%lu for fd=%d\n", (unsigned long int)thread_id, socket_get_fd(sock))); } else { DEBUG(0,("accept_connection_thread: thread create failed for fd=%d, rc=%d\n", socket_get_fd(sock), rc)); - event_context_destroy(ev); - socket_destroy(sock); - return; + talloc_free(ev2); } } /* called when a SMB connection goes down */ -static void thread_terminate_connection(struct server_connection *conn, const char *reason) +static void thread_terminate_connection(struct event_context *event_ctx, const char *reason) { DEBUG(10,("thread_terminate_connection: reason[%s]\n",reason)); - if (conn) { - talloc_free(conn); - } + talloc_free(event_ctx); /* terminate this thread */ pthread_exit(NULL); /* thread cleanup routine will do actual cleanup */ @@ -342,6 +340,7 @@ static void thread_log_task_id(int fd) write(fd, s, strlen(s)); free(s); } + /**************************************************************************** catch serious errors ****************************************************************************/ @@ -406,7 +405,7 @@ static void thread_fault_handler(int sig) /* called when the process model is selected */ -static void thread_model_init(struct server_context *server) +static void thread_model_init(struct event_context *event_context) { struct mutex_ops m_ops; struct debug_ops d_ops; @@ -438,89 +437,12 @@ static void thread_model_init(struct server_context *server) register_debug_handlers("thread", &d_ops); } -static void thread_model_exit(struct server_context *server, const char *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 }; /* |