The net_stack_driver now uses a reference count to determine when to unload the core. This way the core is not unloaded to early and we don't need to work around the unload by opening ourselfs.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12922 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
317121e102
commit
e89253271b
@ -32,7 +32,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Force the driver to stay loaded in memory
|
// Force the driver to stay loaded in memory
|
||||||
#define STAY_LOADED 0
|
#define STAY_LOADED 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local definitions
|
* Local definitions
|
||||||
@ -139,7 +139,8 @@ device_hooks g_net_stack_driver_hooks =
|
|||||||
NULL /* ->writev entry point */
|
NULL /* ->writev entry point */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct core_module_info * core = NULL;
|
struct core_module_info *g_core = NULL;
|
||||||
|
uint32 g_core_reference_count = 0;
|
||||||
|
|
||||||
#if STAY_LOADED
|
#if STAY_LOADED
|
||||||
int g_stay_loaded_fd = -1;
|
int g_stay_loaded_fd = -1;
|
||||||
@ -194,20 +195,21 @@ _EXPORT status_t init_hardware(void)
|
|||||||
_EXPORT status_t init_driver(void)
|
_EXPORT status_t init_driver(void)
|
||||||
{
|
{
|
||||||
// only get the core module if we don't have it loaded already
|
// only get the core module if we don't have it loaded already
|
||||||
if (!core) {
|
if (!g_core) {
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
rv = get_module(NET_CORE_MODULE_NAME, (module_info **) &core);
|
rv = get_module(NET_CORE_MODULE_NAME, (module_info **) &g_core);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
TRACE((LOGID ERR "init_driver: Argh, can't load " NET_CORE_MODULE_NAME " module: %d\n", rv));
|
TRACE((LOGID ERR "init_driver: Argh, can't load " NET_CORE_MODULE_NAME " module: %d\n", rv));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE((LOGID "init_driver: built %s %s, core = %p\n", __DATE__, __TIME__, core));
|
TRACE((LOGID "init_driver: built %s %s, core = %p\n", __DATE__, __TIME__, g_core));
|
||||||
|
|
||||||
// start the network stack!
|
// start the network stack!
|
||||||
core->start();
|
g_core->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_core_reference_count++;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,14 +221,14 @@ _EXPORT status_t init_driver(void)
|
|||||||
_EXPORT void uninit_driver(void)
|
_EXPORT void uninit_driver(void)
|
||||||
{
|
{
|
||||||
TRACE((LOGID "uninit_driver\n"));
|
TRACE((LOGID "uninit_driver\n"));
|
||||||
|
g_core_reference_count--;
|
||||||
if (core) {
|
|
||||||
#if STAY_LOADED
|
if (g_core && g_core_reference_count == 0) {
|
||||||
// shutdown the network stack
|
// shutdown the network stack
|
||||||
core->stop();
|
g_core->stop();
|
||||||
#endif
|
|
||||||
put_module(NET_CORE_MODULE_NAME);
|
put_module(NET_CORE_MODULE_NAME);
|
||||||
core = NULL;
|
g_core = NULL;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +297,7 @@ static status_t net_stack_close(void *cookie)
|
|||||||
rv = B_ERROR;
|
rv = B_ERROR;
|
||||||
if (nsc->socket) {
|
if (nsc->socket) {
|
||||||
// if a socket was opened on this fd, close it now.
|
// if a socket was opened on this fd, close it now.
|
||||||
rv = core->socket_close(nsc->socket);
|
rv = g_core->socket_close(nsc->socket);
|
||||||
nsc->socket = NULL;
|
nsc->socket = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,9 +347,9 @@ static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t le
|
|||||||
case NET_STACK_SOCKET: {
|
case NET_STACK_SOCKET: {
|
||||||
|
|
||||||
// okay, now try to open a real socket behind this fd/net_stack_cookie pair
|
// okay, now try to open a real socket behind this fd/net_stack_cookie pair
|
||||||
err = core->socket_init(&nsc->socket);
|
err = g_core->socket_init(&nsc->socket);
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
err = core->socket_create(nsc->socket, args->u.socket.family, args->u.socket.type, args->u.socket.proto);
|
err = g_core->socket_create(nsc->socket, args->u.socket.family, args->u.socket.type, args->u.socket.proto);
|
||||||
// TODO: This is where the open flags need to be addressed
|
// TODO: This is where the open flags need to be addressed
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -361,24 +363,24 @@ static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t le
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
case NET_STACK_CONTROL_NET_MODULE: {
|
case NET_STACK_CONTROL_NET_MODULE: {
|
||||||
return core->control_net_module(args->u.control.name, args->u.control.op,
|
return g_core->control_net_module(args->u.control.name, args->u.control.op,
|
||||||
args->u.control.data, args->u.control.length);
|
args->u.control.data, args->u.control.length);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case NET_STACK_CONNECT:
|
case NET_STACK_CONNECT:
|
||||||
return core->socket_connect(nsc->socket, (caddr_t) args->u.sockaddr.addr, args->u.sockaddr.addrlen);
|
return g_core->socket_connect(nsc->socket, (caddr_t) args->u.sockaddr.addr, args->u.sockaddr.addrlen);
|
||||||
|
|
||||||
case NET_STACK_SHUTDOWN:
|
case NET_STACK_SHUTDOWN:
|
||||||
return core->socket_shutdown(nsc->socket, args->u.integer);
|
return g_core->socket_shutdown(nsc->socket, args->u.integer);
|
||||||
|
|
||||||
case NET_STACK_BIND:
|
case NET_STACK_BIND:
|
||||||
return core->socket_bind(nsc->socket, (caddr_t) args->u.sockaddr.addr, args->u.sockaddr.addrlen);
|
return g_core->socket_bind(nsc->socket, (caddr_t) args->u.sockaddr.addr, args->u.sockaddr.addrlen);
|
||||||
|
|
||||||
case NET_STACK_LISTEN:
|
case NET_STACK_LISTEN:
|
||||||
// backlog to set
|
// backlog to set
|
||||||
return core->socket_listen(nsc->socket, args->u.integer);
|
return g_core->socket_listen(nsc->socket, args->u.integer);
|
||||||
|
|
||||||
case NET_STACK_ACCEPT: {
|
case NET_STACK_ACCEPT: {
|
||||||
/* args->u.accept.cookie == net_stack_cookie of the already opened fd
|
/* args->u.accept.cookie == net_stack_cookie of the already opened fd
|
||||||
@ -386,7 +388,7 @@ static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t le
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
net_stack_cookie *ansc = args->u.accept.cookie;
|
net_stack_cookie *ansc = args->u.accept.cookie;
|
||||||
return core->socket_accept(nsc->socket, &ansc->socket, (void *)args->u.accept.addr, &args->u.accept.addrlen);
|
return g_core->socket_accept(nsc->socket, &ansc->socket, (void *)args->u.accept.addr, &args->u.accept.addrlen);
|
||||||
}
|
}
|
||||||
case NET_STACK_SEND:
|
case NET_STACK_SEND:
|
||||||
// TODO: flags gets ignored here...
|
// TODO: flags gets ignored here...
|
||||||
@ -400,7 +402,7 @@ static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t le
|
|||||||
struct msghdr * mh = (struct msghdr *) data;
|
struct msghdr * mh = (struct msghdr *) data;
|
||||||
int retsize;
|
int retsize;
|
||||||
|
|
||||||
err = core->socket_recv(nsc->socket, mh, (caddr_t)&mh->msg_namelen,
|
err = g_core->socket_recv(nsc->socket, mh, (caddr_t)&mh->msg_namelen,
|
||||||
&retsize);
|
&retsize);
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
return retsize;
|
return retsize;
|
||||||
@ -410,41 +412,41 @@ static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t le
|
|||||||
struct msghdr * mh = (struct msghdr *) data;
|
struct msghdr * mh = (struct msghdr *) data;
|
||||||
int retsize;
|
int retsize;
|
||||||
|
|
||||||
err = core->socket_send(nsc->socket, mh, mh->msg_flags,
|
err = g_core->socket_send(nsc->socket, mh, mh->msg_flags,
|
||||||
&retsize);
|
&retsize);
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
return retsize;
|
return retsize;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
case NET_STACK_SYSCTL:
|
case NET_STACK_SYSCTL:
|
||||||
return core->net_sysctl(args->u.sysctl.name, args->u.sysctl.namelen,
|
return g_core->net_sysctl(args->u.sysctl.name, args->u.sysctl.namelen,
|
||||||
args->u.sysctl.oldp, args->u.sysctl.oldlenp,
|
args->u.sysctl.oldp, args->u.sysctl.oldlenp,
|
||||||
args->u.sysctl.newp, args->u.sysctl.newlen);
|
args->u.sysctl.newp, args->u.sysctl.newlen);
|
||||||
|
|
||||||
case NET_STACK_GETSOCKOPT:
|
case NET_STACK_GETSOCKOPT:
|
||||||
return core->socket_getsockopt(nsc->socket, args->u.sockopt.level, args->u.sockopt.option,
|
return g_core->socket_getsockopt(nsc->socket, args->u.sockopt.level, args->u.sockopt.option,
|
||||||
args->u.sockopt.optval, (size_t *) &args->u.sockopt.optlen);
|
args->u.sockopt.optval, (size_t *) &args->u.sockopt.optlen);
|
||||||
|
|
||||||
case NET_STACK_SETSOCKOPT:
|
case NET_STACK_SETSOCKOPT:
|
||||||
return core->socket_setsockopt(nsc->socket, args->u.sockopt.level, args->u.sockopt.option,
|
return g_core->socket_setsockopt(nsc->socket, args->u.sockopt.level, args->u.sockopt.option,
|
||||||
(const void *) args->u.sockopt.optval, args->u.sockopt.optlen);
|
(const void *) args->u.sockopt.optval, args->u.sockopt.optlen);
|
||||||
|
|
||||||
case NET_STACK_GETSOCKNAME:
|
case NET_STACK_GETSOCKNAME:
|
||||||
return core->socket_getsockname(nsc->socket, args->u.sockaddr.addr, &args->u.sockaddr.addrlen);
|
return g_core->socket_getsockname(nsc->socket, args->u.sockaddr.addr, &args->u.sockaddr.addrlen);
|
||||||
|
|
||||||
case NET_STACK_GETPEERNAME:
|
case NET_STACK_GETPEERNAME:
|
||||||
return core->socket_getpeername(nsc->socket, args->u.sockaddr.addr, &args->u.sockaddr.addrlen);
|
return g_core->socket_getpeername(nsc->socket, args->u.sockaddr.addr, &args->u.sockaddr.addrlen);
|
||||||
|
|
||||||
case B_SET_BLOCKING_IO: {
|
case B_SET_BLOCKING_IO: {
|
||||||
int off = false;
|
int off = false;
|
||||||
nsc->open_flags &= ~O_NONBLOCK;
|
nsc->open_flags &= ~O_NONBLOCK;
|
||||||
return core->socket_ioctl(nsc->socket, FIONBIO, (caddr_t) &off);
|
return g_core->socket_ioctl(nsc->socket, FIONBIO, (caddr_t) &off);
|
||||||
}
|
}
|
||||||
|
|
||||||
case B_SET_NONBLOCKING_IO: {
|
case B_SET_NONBLOCKING_IO: {
|
||||||
int on = true;
|
int on = true;
|
||||||
nsc->open_flags |= O_NONBLOCK;
|
nsc->open_flags |= O_NONBLOCK;
|
||||||
return core->socket_ioctl(nsc->socket, FIONBIO, (caddr_t) &on);
|
return g_core->socket_ioctl(nsc->socket, FIONBIO, (caddr_t) &on);
|
||||||
}
|
}
|
||||||
|
|
||||||
case NET_STACK_SELECT:
|
case NET_STACK_SELECT:
|
||||||
@ -459,7 +461,7 @@ static status_t net_stack_control(void *cookie, uint32 op, void *data, size_t le
|
|||||||
default:
|
default:
|
||||||
if (nsc->socket)
|
if (nsc->socket)
|
||||||
// pass any unhandled opcode to the stack
|
// pass any unhandled opcode to the stack
|
||||||
return core->socket_ioctl(nsc->socket, op, data);
|
return g_core->socket_ioctl(nsc->socket, op, data);
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -492,7 +494,7 @@ static status_t net_stack_read(void *cookie,
|
|||||||
iov.iov_base = buffer;
|
iov.iov_base = buffer;
|
||||||
iov.iov_len = *readlen;
|
iov.iov_len = *readlen;
|
||||||
|
|
||||||
error = core->socket_readv(nsc->socket, &iov, &flags);
|
error = g_core->socket_readv(nsc->socket, &iov, &flags);
|
||||||
*readlen = error;
|
*readlen = error;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -524,7 +526,7 @@ static status_t net_stack_write(void *cookie,
|
|||||||
#endif
|
#endif
|
||||||
if (*writelen >= strlen(STOP_CMD) &&
|
if (*writelen >= strlen(STOP_CMD) &&
|
||||||
strncmp(buffer, STOP_CMD, strlen(STOP_CMD)) == 0)
|
strncmp(buffer, STOP_CMD, strlen(STOP_CMD)) == 0)
|
||||||
return core->stop();
|
return g_core->stop();
|
||||||
|
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
};
|
};
|
||||||
@ -532,7 +534,7 @@ static status_t net_stack_write(void *cookie,
|
|||||||
iov.iov_base = (void*)buffer;
|
iov.iov_base = (void*)buffer;
|
||||||
iov.iov_len = *writelen;
|
iov.iov_len = *writelen;
|
||||||
|
|
||||||
error = core->socket_writev(nsc->socket, &iov, flags);
|
error = g_core->socket_writev(nsc->socket, &iov, flags);
|
||||||
*writelen = error;
|
*writelen = error;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -580,7 +582,7 @@ static status_t net_stack_select(void *cookie, uint8 event, uint32 ref, selectsy
|
|||||||
release_sem(nsc->selecters_lock);
|
release_sem(nsc->selecters_lock);
|
||||||
|
|
||||||
// start (or continue) to monitor for socket event
|
// start (or continue) to monitor for socket event
|
||||||
return core->socket_set_event_callback(nsc->socket, on_socket_event, nsc, event);
|
return g_core->socket_set_event_callback(nsc->socket, on_socket_event, nsc, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -628,7 +630,7 @@ static status_t net_stack_deselect(void *cookie, uint8 event, selectsync *sync)
|
|||||||
|
|
||||||
if (nsc->selecters == NULL)
|
if (nsc->selecters == NULL)
|
||||||
// selecters list is empty: no need to monitor socket events anymore
|
// selecters list is empty: no need to monitor socket events anymore
|
||||||
core->socket_set_event_callback(nsc->socket, NULL, NULL, event);
|
g_core->socket_set_event_callback(nsc->socket, NULL, NULL, event);
|
||||||
|
|
||||||
// unlock the selecters list
|
// unlock the selecters list
|
||||||
return release_sem(nsc->selecters_lock);
|
return release_sem(nsc->selecters_lock);
|
||||||
|
Loading…
Reference in New Issue
Block a user