* Now uses DoublyLinkedList instead of the struct list C stuff.
* Cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29981 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -35,13 +35,16 @@
|
|||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
|
|
||||||
struct net_socket_private : net_socket {
|
struct net_socket_private;
|
||||||
struct list_link link;
|
typedef DoublyLinkedList<net_socket_private> SocketList;
|
||||||
|
|
||||||
|
struct net_socket_private
|
||||||
|
: net_socket, DoublyLinkedListLinkImpl<net_socket_private> {
|
||||||
team_id owner;
|
team_id owner;
|
||||||
uint32 max_backlog;
|
uint32 max_backlog;
|
||||||
uint32 child_count;
|
uint32 child_count;
|
||||||
struct list pending_children;
|
SocketList pending_children;
|
||||||
struct list connected_children;
|
SocketList connected_children;
|
||||||
|
|
||||||
struct select_sync_pool* select_pool;
|
struct select_sync_pool* select_pool;
|
||||||
mutex lock;
|
mutex lock;
|
||||||
@@ -55,8 +58,8 @@ int socket_setsockopt(net_socket *socket, int level, int option,
|
|||||||
const void* value, int length);
|
const void* value, int length);
|
||||||
|
|
||||||
|
|
||||||
struct list sSocketList;
|
static SocketList sSocketList;
|
||||||
mutex sSocketLock;
|
static mutex sSocketLock;
|
||||||
|
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
@@ -77,14 +80,9 @@ compute_user_iovec_length(iovec *userVec, uint32 count)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
delete_children(struct list *list)
|
delete_children(SocketList& list)
|
||||||
{
|
{
|
||||||
while (true) {
|
while (net_socket_private* child = list.RemoveHead()) {
|
||||||
net_socket_private *child
|
|
||||||
= (net_socket_private *)list_remove_head_item(list);
|
|
||||||
if (child == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
child->parent = NULL;
|
child->parent = NULL;
|
||||||
socket_delete(child);
|
socket_delete(child);
|
||||||
}
|
}
|
||||||
@@ -113,11 +111,6 @@ create_socket(int family, int type, int protocol, net_socket_private **_socket)
|
|||||||
socket->receive.low_water_mark = 1;
|
socket->receive.low_water_mark = 1;
|
||||||
socket->receive.timeout = B_INFINITE_TIMEOUT;
|
socket->receive.timeout = B_INFINITE_TIMEOUT;
|
||||||
|
|
||||||
list_init_etc(&socket->pending_children, offsetof(net_socket_private,
|
|
||||||
link));
|
|
||||||
list_init_etc(&socket->connected_children, offsetof(net_socket_private,
|
|
||||||
link));
|
|
||||||
|
|
||||||
status_t status = get_domain_protocols(socket);
|
status_t status = get_domain_protocols(socket);
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
mutex_destroy(&socket->lock);
|
mutex_destroy(&socket->lock);
|
||||||
@@ -243,7 +236,7 @@ socket_open(int family, int type, int protocol, net_socket **_socket)
|
|||||||
socket->owner = team_get_current_team_id();
|
socket->owner = team_get_current_team_id();
|
||||||
|
|
||||||
mutex_lock(&sSocketLock);
|
mutex_lock(&sSocketLock);
|
||||||
list_add_item(&sSocketList, socket);
|
sSocketList.Add(socket);
|
||||||
mutex_unlock(&sSocketLock);
|
mutex_unlock(&sSocketLock);
|
||||||
|
|
||||||
*_socket = socket;
|
*_socket = socket;
|
||||||
@@ -411,10 +404,12 @@ socket_get_next_stat(uint32 *_cookie, int family, struct net_stat *stat)
|
|||||||
MutexLocker locker(sSocketLock);
|
MutexLocker locker(sSocketLock);
|
||||||
|
|
||||||
net_socket_private* socket = NULL;
|
net_socket_private* socket = NULL;
|
||||||
|
SocketList::Iterator iterator = sSocketList.GetIterator();
|
||||||
uint32 cookie = *_cookie;
|
uint32 cookie = *_cookie;
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
while ((socket = (net_socket_private *)list_get_next_item(&sSocketList,
|
while (iterator.HasNext()) {
|
||||||
socket)) != NULL) {
|
socket = iterator.Next();
|
||||||
|
|
||||||
// TODO: also traverse the pending connections
|
// TODO: also traverse the pending connections
|
||||||
if (count == cookie)
|
if (count == cookie)
|
||||||
break;
|
break;
|
||||||
@@ -479,7 +474,7 @@ socket_spawn_pending(net_socket *_parent, net_socket **_socket)
|
|||||||
memcpy(&socket->peer, &parent->peer, parent->peer.ss_len);
|
memcpy(&socket->peer, &parent->peer, parent->peer.ss_len);
|
||||||
|
|
||||||
// add to the parent's list of pending connections
|
// add to the parent's list of pending connections
|
||||||
list_add_item(&parent->pending_children, socket);
|
parent->pending_children.Add(socket);
|
||||||
socket->parent = parent;
|
socket->parent = parent;
|
||||||
parent->child_count++;
|
parent->child_count++;
|
||||||
|
|
||||||
@@ -497,12 +492,12 @@ socket_delete(net_socket *_socket)
|
|||||||
panic("socket still has a parent!");
|
panic("socket still has a parent!");
|
||||||
|
|
||||||
mutex_lock(&sSocketLock);
|
mutex_lock(&sSocketLock);
|
||||||
list_remove_item(&sSocketList, socket);
|
sSocketList.Remove(socket);
|
||||||
mutex_unlock(&sSocketLock);
|
mutex_unlock(&sSocketLock);
|
||||||
|
|
||||||
// also delete all children of this socket
|
// also delete all children of this socket
|
||||||
delete_children(&socket->pending_children);
|
delete_children(socket->pending_children);
|
||||||
delete_children(&socket->connected_children);
|
delete_children(socket->connected_children);
|
||||||
|
|
||||||
put_domain_protocols(socket);
|
put_domain_protocols(socket);
|
||||||
mutex_destroy(&socket->lock);
|
mutex_destroy(&socket->lock);
|
||||||
@@ -517,8 +512,7 @@ socket_dequeue_connected(net_socket *_parent, net_socket **_socket)
|
|||||||
|
|
||||||
mutex_lock(&parent->lock);
|
mutex_lock(&parent->lock);
|
||||||
|
|
||||||
net_socket_private *socket = (net_socket_private *)list_remove_head_item(
|
net_socket_private* socket = parent->connected_children.RemoveHead();
|
||||||
&parent->connected_children);
|
|
||||||
if (socket != NULL) {
|
if (socket != NULL) {
|
||||||
socket->parent = NULL;
|
socket->parent = NULL;
|
||||||
parent->child_count--;
|
parent->child_count--;
|
||||||
@@ -531,7 +525,7 @@ socket_dequeue_connected(net_socket *_parent, net_socket **_socket)
|
|||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
mutex_lock(&sSocketLock);
|
mutex_lock(&sSocketLock);
|
||||||
list_add_item(&sSocketList, socket);
|
sSocketList.Add(socket);
|
||||||
mutex_unlock(&sSocketLock);
|
mutex_unlock(&sSocketLock);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -544,15 +538,7 @@ socket_count_connected(net_socket *_parent)
|
|||||||
net_socket_private* parent = (net_socket_private*)_parent;
|
net_socket_private* parent = (net_socket_private*)_parent;
|
||||||
|
|
||||||
MutexLocker _(parent->lock);
|
MutexLocker _(parent->lock);
|
||||||
|
return parent->connected_children.Count();
|
||||||
ssize_t count = 0;
|
|
||||||
void *item = NULL;
|
|
||||||
while ((item = list_get_next_item(&parent->connected_children,
|
|
||||||
item)) != NULL) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -565,33 +551,29 @@ socket_set_max_backlog(net_socket *_socket, uint32 backlog)
|
|||||||
if (backlog > 256)
|
if (backlog > 256)
|
||||||
backlog = 256;
|
backlog = 256;
|
||||||
|
|
||||||
mutex_lock(&socket->lock);
|
MutexLocker _(socket->lock);
|
||||||
|
|
||||||
// first remove the pending connections, then the already connected
|
// first remove the pending connections, then the already connected
|
||||||
// ones as needed
|
// ones as needed
|
||||||
net_socket_private* child;
|
net_socket_private* child;
|
||||||
while (socket->child_count > backlog
|
while (socket->child_count > backlog
|
||||||
&& (child = (net_socket_private *)list_remove_tail_item(
|
&& (child = socket->pending_children.RemoveTail()) != NULL) {
|
||||||
&socket->pending_children)) != NULL) {
|
|
||||||
child->parent = NULL;
|
child->parent = NULL;
|
||||||
socket->child_count--;
|
socket->child_count--;
|
||||||
}
|
}
|
||||||
while (socket->child_count > backlog
|
while (socket->child_count > backlog
|
||||||
&& (child = (net_socket_private *)list_remove_tail_item(
|
&& (child = socket->connected_children.RemoveTail()) != NULL) {
|
||||||
&socket->connected_children)) != NULL) {
|
|
||||||
child->parent = NULL;
|
child->parent = NULL;
|
||||||
socket_delete(child);
|
socket_delete(child);
|
||||||
socket->child_count--;
|
socket->child_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket->max_backlog = backlog;
|
socket->max_backlog = backlog;
|
||||||
mutex_unlock(&socket->lock);
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*! The socket has been connected. It will be moved to the connected queue
|
||||||
The socket has been connected. It will be moved to the connected queue
|
|
||||||
of its parent socket.
|
of its parent socket.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
@@ -601,16 +583,15 @@ socket_connected(net_socket *socket)
|
|||||||
if (parent == NULL)
|
if (parent == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
mutex_lock(&parent->lock);
|
MutexLocker _(&parent->lock);
|
||||||
|
|
||||||
list_remove_item(&parent->pending_children, socket);
|
parent->pending_children.Remove((net_socket_private*)socket);
|
||||||
list_add_item(&parent->connected_children, socket);
|
parent->connected_children.Add((net_socket_private*)socket);
|
||||||
|
|
||||||
// notify parent
|
// notify parent
|
||||||
if (parent->select_pool)
|
if (parent->select_pool)
|
||||||
notify_select_event_pool(parent->select_pool, B_SELECT_READ);
|
notify_select_event_pool(parent->select_pool, B_SELECT_READ);
|
||||||
|
|
||||||
mutex_unlock(&parent->lock);
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,13 +648,8 @@ socket_cancel_notification(net_socket *_socket, uint8 event, selectsync *sync)
|
|||||||
{
|
{
|
||||||
net_socket_private* socket = (net_socket_private*)_socket;
|
net_socket_private* socket = (net_socket_private*)_socket;
|
||||||
|
|
||||||
mutex_lock(&socket->lock);
|
MutexLocker _(socket->lock);
|
||||||
|
return remove_select_sync_pool_entry(&socket->select_pool, sync, event);
|
||||||
status_t status = remove_select_sync_pool_entry(&socket->select_pool,
|
|
||||||
sync, event);
|
|
||||||
|
|
||||||
mutex_unlock(&socket->lock);
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -685,14 +661,12 @@ socket_notify(net_socket *_socket, uint8 event, int32 value)
|
|||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case B_SELECT_READ:
|
case B_SELECT_READ:
|
||||||
if ((ssize_t)socket->receive.low_water_mark > value
|
if ((ssize_t)socket->receive.low_water_mark > value && value >= B_OK)
|
||||||
&& value >= B_OK)
|
|
||||||
notify = false;
|
notify = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_SELECT_WRITE:
|
case B_SELECT_WRITE:
|
||||||
if ((ssize_t)socket->send.low_water_mark > value
|
if ((ssize_t)socket->send.low_water_mark > value && value >= B_OK)
|
||||||
&& value >= B_OK)
|
|
||||||
notify = false;
|
notify = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -701,12 +675,11 @@ socket_notify(net_socket *_socket, uint8 event, int32 value)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&socket->lock);
|
MutexLocker _(socket->lock);
|
||||||
|
|
||||||
if (notify && socket->select_pool)
|
if (notify && socket->select_pool)
|
||||||
notify_select_event_pool(socket->select_pool, event);
|
notify_select_event_pool(socket->select_pool, event);
|
||||||
|
|
||||||
mutex_unlock(&socket->lock);
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1426,16 +1399,11 @@ socket_std_ops(int32 op, ...)
|
|||||||
switch (op) {
|
switch (op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT:
|
||||||
{
|
{
|
||||||
// TODO: this is currently done in the net_stack driver
|
new (&sSocketList) SocketList;
|
||||||
// initialize the main stack if not done so already
|
|
||||||
//module_info *module;
|
|
||||||
//return get_module(NET_STARTER_MODULE_NAME, &module);
|
|
||||||
list_init_etc(&sSocketList, offsetof(net_socket_private, link));
|
|
||||||
mutex_init(&sSocketLock, "socket list");
|
mutex_init(&sSocketLock, "socket list");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
//return put_module(NET_STARTER_MODULE_NAME);
|
|
||||||
mutex_destroy(&sSocketLock);
|
mutex_destroy(&sSocketLock);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user