summaryrefslogtreecommitdiff
path: root/source4/smbd/process_thread.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-01-30 00:54:57 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:09:22 -0500
commit55d4d36993293fee914a009f1d8f05810e347f2b (patch)
tree587a9bafd1c8df901aad8766acb0fe9ef4c3d8c0 /source4/smbd/process_thread.c
parent5540449f1cd9d9a6efab59f2bf47be4e1487ffc2 (diff)
downloadsamba-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.c164
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
};
/*