From d47eebf30b1bbf95bf0fc982d1d7aff7d58f8dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 11 Nov 2006 12:27:30 +0000 Subject: [PATCH] * The select()/deselect() hooks now actually call the socket's request_notification() and cancel_notification() functions. * Completey dropped the old select code, as well as any R5 compatibility stuff. If we ever need it again, it's still in SVN history. * The socket module was put in uninit_driver() for no reason. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19256 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/net/net_stack_driver.h | 47 +-- .../drivers/network/stack/kernel_stack.cpp | 319 +++++------------- 2 files changed, 85 insertions(+), 281 deletions(-) diff --git a/headers/private/net/net_stack_driver.h b/headers/private/net/net_stack_driver.h index 3629d14cc0..9a53357b74 100644 --- a/headers/private/net/net_stack_driver.h +++ b/headers/private/net/net_stack_driver.h @@ -15,8 +15,8 @@ // Forward declaration struct sockaddr; -#define NET_STACK_DRIVER_DEV "net/stack" -#define NET_STACK_DRIVER_PATH "/dev/" NET_STACK_DRIVER_DEV +#define NET_STACK_DRIVER_DEVICE "net/stack" +#define NET_STACK_DRIVER_PATH "/dev/" NET_STACK_DRIVER_DEVICE enum { NET_STACK_IOCTL_BASE = 8800, @@ -105,47 +105,4 @@ struct control_net_module_args { // used by NET_STACK_CONTROL_NET_MODULE size_t length; }; -/* - Userland stack driver on_socket_event() callback mecanism implementation: - the driver start a kernel thread waiting on a port for - a NET_STACK_SOCKET_EVENT_MSG message, which come with a socket_event_data block. - - The on_socket_event() mechanism stay in driver (kernelland) because it's - only there we can call kernel's notify_select_event() on BONE systems. - For non-BONE systems, we use our own r5_notify_select_event() - implementation, that could be moved into the userland net_server code, - but it'll have split (again!) the /dev/net/stack driver code... -*/ - -struct notify_socket_event_args { // used by NET_STACK_NOTIFY_SOCKET_EVENT - port_id notify_port; // port waiting for notification, -1 = stop notify - void *cookie; // this cookie value will be pass back in the socket_event_args -}; - -#define NET_STACK_SOCKET_EVENT_NOTIFICATION 'sevn' - -struct socket_event_data { - uint32 event; // B_SELECT_READ, B_SELECT_WRITE or B_SELECT_ERROR - void *cookie; // The cookie as set in notify_socket_event_args for this socket -}; - -/* - R5.0.3 and before select() kernel support is too buggy to be used, so - here are the structures we used to support select() on sockets, and *only* on - sockets! -*/ - -struct select_args { // used by NET_STACK_SELECT and NET_STACK_DESELECT - struct selectsync *sync; // in fact, it's the area_id of a r5_selectsync struct!!! - uint32 ref; -}; - -struct r5_selectsync { - sem_id lock; // lock this r5_selectsync - sem_id wakeup; // sem to release to wakeup select() - struct fd_set rbits; // read event bits field - struct fd_set wbits; // write event bits field - struct fd_set ebits; // exception event bits field -}; - #endif /* NET_STACK_DRIVER_H */ diff --git a/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp b/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp index 3541757a8e..f1fd9d8a25 100644 --- a/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp +++ b/src/add-ons/kernel/drivers/network/stack/kernel_stack.cpp @@ -32,43 +32,11 @@ #endif -// Local definitions - -// this struct will store one select() event to monitor per thread -typedef struct selecter { - struct selecter *next; - thread_id thread; - uint32 event; - selectsync *sync; - uint32 ref; -} selecter; - // the cookie we attach to each file descriptor opened on our driver entry -typedef struct net_stack_cookie { - net_socket *socket; // NULL before ioctl(fd, NET_STACK_SOCKET/_ACCEPT) - sem_id selecters_lock; // protect the selecters linked-list - selecter *selecters; // the select()'ers lists (thread-aware) -} net_stack_cookie; - -// TODO: disabled -/* To unload this driver execute - * $ echo unload > /dev/net/stack - * As soon as the last app stops using sockets the netstack will be unloaded. - */ -//static const char *kUnloadCommand = "unload"; - - -// prototypes of device hooks functions -static status_t net_stack_open(const char *name, uint32 flags, void **_cookie); -static status_t net_stack_close(void *cookie); -static status_t net_stack_free_cookie(void *cookie); -static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t length); -static status_t net_stack_read(void *cookie, off_t pos, void *data, size_t *_length); -static status_t net_stack_write(void *cookie, off_t pos, const void *data, size_t *_length); -static status_t net_stack_select(void *cookie, uint8 event, uint32 ref, selectsync *sync); -static status_t net_stack_deselect(void *cookie, uint8 event, selectsync *sync); -static status_t net_stack_readv(void *cookie, off_t pos, const iovec *vecs, size_t count, size_t *_length); -static status_t net_stack_writev(void *cookie, off_t pos, const iovec *vecs, size_t count, size_t *_length); +struct net_stack_cookie { + net_socket *socket; + // is set using NET_STACK_SOCKET/_ACCEPT +}; int32 api_version = B_CUR_DRIVER_API_VERSION; @@ -128,48 +96,6 @@ check_args(ArgType &args, void *data, size_t length) } -#if 0 -static void -on_socket_event(void * socket, uint32 event, void *_cookie) -{ - net_stack_cookie *cookie = (net_stack_cookie *) _cookie; - selecter *s; - - if (!cookie) - return; - - if (cookie->socket != socket) { - ERROR("on_socket_event(%p, %ld, %p): socket is higly suspect! Aborting.\n", - socket, event, cookie); - return; - } - - TRACE("on_socket_event(%p, %ld, %p)\n", socket, event, cookie); - - // lock the selecters list - if (acquire_sem(cookie->selecters_lock) != B_OK) - return; - - s = cookie->selecters; - while (s) { - if (s->event == event) - // notify this selecter (thread/event pair) -#ifdef COMPILE_FOR_R5 - notify_select_event(s->sync, s->ref); -#else - notify_select_event(s->sync, s->ref, event); -#endif - - s = s->next; - } - - // unlock the selecters list - release_sem(cookie->selecters_lock); - return; -} -#endif - - #ifdef DEBUG static const char* opcode_name(int op) @@ -226,81 +152,6 @@ opcode_name(int op) #endif // DEBUG -// #pragma mark - driver - - -/** Do we init ourselves? If we're in safe mode we'll decline so if things - * screw up we can boot and delete the broken driver! - * After my experiences earlier - a good idea! - */ - -status_t -init_hardware(void) -{ - void *settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); - if (settings != NULL) { - // we got a pointer, now get settings... - bool safemode = get_driver_boolean_parameter(settings, B_SAFEMODE_SAFE_MODE, false, false); - // now get rid of settings - unload_driver_settings(settings); - - if (safemode) { - WARN("init_hardware: declining offer to join the party.\n"); - return B_ERROR; - } - } - - TRACE("init_hardware done.\n"); - return B_OK; -} - - -status_t -init_driver(void) -{ - - return B_OK; -} - - -void -uninit_driver(void) -{ - TRACE("uninit_driver\n"); - - put_module(NET_SOCKET_MODULE_NAME); -} - - -const char ** -publish_devices(void) -{ - static const char *devices[] = { NET_STACK_DRIVER_DEV, NULL }; - - return devices; -} - - -device_hooks* -find_device(const char* device_name) -{ - static device_hooks hooks = { - net_stack_open, - net_stack_close, - net_stack_free_cookie, - net_stack_control, - net_stack_read, - net_stack_write, - net_stack_select, - net_stack_deselect, - net_stack_readv, - net_stack_writev, - }; - - return &hooks; -} - - // #pragma mark - device @@ -321,11 +172,7 @@ net_stack_open(const char *name, uint32 flags, void **_cookie) if (cookie == NULL) return B_NO_MEMORY; - memset(cookie, 0, sizeof(net_stack_cookie)); - cookie->socket = NULL; // the socket will be allocated in NET_STACK_SOCKET ioctl - cookie->selecters_lock = create_sem(1, "socket_selecters_lock"); - - // attach this new net_socket_cookie to file descriptor + cookie->socket = NULL; *_cookie = cookie; TRACE("net_stack_open(%s, %s%s) return this cookie: %p\n", @@ -357,28 +204,18 @@ static status_t net_stack_free_cookie(void *_cookie) { net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - selecter *s; TRACE("net_stack_free_cookie(%p)\n", cookie); - - // free the selecters list - delete_sem(cookie->selecters_lock); - s = cookie->selecters; - while (s) { - selecter *tmp = s; - s = s->next; - free(tmp); - } if (cookie->socket != NULL) sSocket->free(cookie->socket); - // free the cookie free(cookie); if (atomic_add(&sOpenCount, -1) == 1) { // the last reference to us has been removed, unload the networking - // stack again + // stack again (it will only be actually unloaded in case there is + // no interface defined) put_module(NET_SOCKET_MODULE_NAME); } @@ -692,40 +529,13 @@ static status_t net_stack_select(void *_cookie, uint8 event, uint32 ref, selectsync *sync) { net_stack_cookie *cookie = (net_stack_cookie *)_cookie; - status_t status; TRACE("net_stack_select(%p, %d, %ld, %p)\n", cookie, event, ref, sync); if (cookie->socket == NULL) return B_BAD_VALUE; - selecter *s = (selecter *)malloc(sizeof(selecter)); - if (s == NULL) - return B_NO_MEMORY; - - s->thread = find_thread(NULL); - s->event = event; - s->sync = sync; - s->ref = ref; - - // lock the selecters list - status = acquire_sem(cookie->selecters_lock); - if (status != B_OK) { - free(s); - return status; - } - - // add it to selecters list - s->next = cookie->selecters; - cookie->selecters = s; - - // unlock the selecters list - release_sem(cookie->selecters_lock); - - // start (or continue) to monitor for socket event - // TODO: enable select() notification -// return sSocket->socket_set_event_callback(cookie->socket, on_socket_event, cookie, event); - return B_OK; + return sSocket->request_notification(cookie->socket, event, ref, sync); } @@ -736,44 +546,81 @@ net_stack_deselect(void *_cookie, uint8 event, selectsync *sync) TRACE("net_stack_deselect(%p, %d, %p)\n", cookie, event, sync); - if (!cookie || !cookie->socket) + if (cookie->socket == NULL) return B_BAD_VALUE; - // lock the selecters list - status_t status = acquire_sem(cookie->selecters_lock); - if (status != B_OK) - return status; - - thread_id currentThread = find_thread(NULL);; - selecter *previous = NULL; - selecter *s = cookie->selecters; - - while (s) { - if (s->thread == currentThread - && s->event == event && s->sync == sync) { - // selecter found! - break; - } - - previous = s; - s = s->next; - } - - if (s != NULL) { - // remove it from selecters list - if (previous) - previous->next = s->next; - else - cookie->selecters = s->next; - free(s); - } - - // TODO: enable deselect() - if (cookie->selecters == NULL) { - // selecters list is empty: no need to monitor socket events anymore - //sSocket->socket_set_event_callback(cookie->socket, NULL, NULL, event); - } - - // unlock the selecters list - return release_sem(cookie->selecters_lock); + return sSocket->cancel_notification(cookie->socket, event, sync); +} + + +// #pragma mark - driver + + +/** Do we init ourselves? If we're in safe mode we'll decline so if things + * screw up we can boot and delete the broken driver! + * After my experiences earlier - a good idea! + */ + +status_t +init_hardware(void) +{ + void *settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); + if (settings != NULL) { + // we got a pointer, now get settings... + bool safemode = get_driver_boolean_parameter(settings, B_SAFEMODE_SAFE_MODE, false, false); + // now get rid of settings + unload_driver_settings(settings); + + if (safemode) { + WARN("net_stack: Safemode! Declining offer to join the party.\n"); + return B_ERROR; + } + } + + return B_OK; +} + + +status_t +init_driver(void) +{ + return B_OK; +} + + +void +uninit_driver(void) +{ +} + + +const char ** +publish_devices(void) +{ + static const char *devices[] = { + NET_STACK_DRIVER_DEVICE, + NULL + }; + + return devices; +} + + +device_hooks* +find_device(const char* device_name) +{ + static device_hooks hooks = { + net_stack_open, + net_stack_close, + net_stack_free_cookie, + net_stack_control, + net_stack_read, + net_stack_write, + net_stack_select, + net_stack_deselect, + net_stack_readv, + net_stack_writev, + }; + + return &hooks; }