* 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.
|
||||
*
|
||||
* Authors:
|
||||
@@ -35,13 +35,16 @@
|
||||
#include "utility.h"
|
||||
|
||||
|
||||
struct net_socket_private : net_socket {
|
||||
struct list_link link;
|
||||
struct net_socket_private;
|
||||
typedef DoublyLinkedList<net_socket_private> SocketList;
|
||||
|
||||
struct net_socket_private
|
||||
: net_socket, DoublyLinkedListLinkImpl<net_socket_private> {
|
||||
team_id owner;
|
||||
uint32 max_backlog;
|
||||
uint32 child_count;
|
||||
struct list pending_children;
|
||||
struct list connected_children;
|
||||
SocketList pending_children;
|
||||
SocketList connected_children;
|
||||
|
||||
struct select_sync_pool* select_pool;
|
||||
mutex lock;
|
||||
@@ -55,8 +58,8 @@ int socket_setsockopt(net_socket *socket, int level, int option,
|
||||
const void* value, int length);
|
||||
|
||||
|
||||
struct list sSocketList;
|
||||
mutex sSocketLock;
|
||||
static SocketList sSocketList;
|
||||
static mutex sSocketLock;
|
||||
|
||||
|
||||
static size_t
|
||||
@@ -77,14 +80,9 @@ compute_user_iovec_length(iovec *userVec, uint32 count)
|
||||
|
||||
|
||||
static void
|
||||
delete_children(struct list *list)
|
||||
delete_children(SocketList& list)
|
||||
{
|
||||
while (true) {
|
||||
net_socket_private *child
|
||||
= (net_socket_private *)list_remove_head_item(list);
|
||||
if (child == NULL)
|
||||
break;
|
||||
|
||||
while (net_socket_private* child = list.RemoveHead()) {
|
||||
child->parent = NULL;
|
||||
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.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);
|
||||
if (status < B_OK) {
|
||||
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();
|
||||
|
||||
mutex_lock(&sSocketLock);
|
||||
list_add_item(&sSocketList, socket);
|
||||
sSocketList.Add(socket);
|
||||
mutex_unlock(&sSocketLock);
|
||||
|
||||
*_socket = socket;
|
||||
@@ -411,10 +404,12 @@ socket_get_next_stat(uint32 *_cookie, int family, struct net_stat *stat)
|
||||
MutexLocker locker(sSocketLock);
|
||||
|
||||
net_socket_private* socket = NULL;
|
||||
SocketList::Iterator iterator = sSocketList.GetIterator();
|
||||
uint32 cookie = *_cookie;
|
||||
uint32 count = 0;
|
||||
while ((socket = (net_socket_private *)list_get_next_item(&sSocketList,
|
||||
socket)) != NULL) {
|
||||
while (iterator.HasNext()) {
|
||||
socket = iterator.Next();
|
||||
|
||||
// TODO: also traverse the pending connections
|
||||
if (count == cookie)
|
||||
break;
|
||||
@@ -479,7 +474,7 @@ socket_spawn_pending(net_socket *_parent, net_socket **_socket)
|
||||
memcpy(&socket->peer, &parent->peer, parent->peer.ss_len);
|
||||
|
||||
// add to the parent's list of pending connections
|
||||
list_add_item(&parent->pending_children, socket);
|
||||
parent->pending_children.Add(socket);
|
||||
socket->parent = parent;
|
||||
parent->child_count++;
|
||||
|
||||
@@ -497,12 +492,12 @@ socket_delete(net_socket *_socket)
|
||||
panic("socket still has a parent!");
|
||||
|
||||
mutex_lock(&sSocketLock);
|
||||
list_remove_item(&sSocketList, socket);
|
||||
sSocketList.Remove(socket);
|
||||
mutex_unlock(&sSocketLock);
|
||||
|
||||
// also delete all children of this socket
|
||||
delete_children(&socket->pending_children);
|
||||
delete_children(&socket->connected_children);
|
||||
delete_children(socket->pending_children);
|
||||
delete_children(socket->connected_children);
|
||||
|
||||
put_domain_protocols(socket);
|
||||
mutex_destroy(&socket->lock);
|
||||
@@ -517,8 +512,7 @@ socket_dequeue_connected(net_socket *_parent, net_socket **_socket)
|
||||
|
||||
mutex_lock(&parent->lock);
|
||||
|
||||
net_socket_private *socket = (net_socket_private *)list_remove_head_item(
|
||||
&parent->connected_children);
|
||||
net_socket_private* socket = parent->connected_children.RemoveHead();
|
||||
if (socket != NULL) {
|
||||
socket->parent = NULL;
|
||||
parent->child_count--;
|
||||
@@ -531,7 +525,7 @@ socket_dequeue_connected(net_socket *_parent, net_socket **_socket)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
mutex_lock(&sSocketLock);
|
||||
list_add_item(&sSocketList, socket);
|
||||
sSocketList.Add(socket);
|
||||
mutex_unlock(&sSocketLock);
|
||||
|
||||
return B_OK;
|
||||
@@ -544,15 +538,7 @@ socket_count_connected(net_socket *_parent)
|
||||
net_socket_private* parent = (net_socket_private*)_parent;
|
||||
|
||||
MutexLocker _(parent->lock);
|
||||
|
||||
ssize_t count = 0;
|
||||
void *item = NULL;
|
||||
while ((item = list_get_next_item(&parent->connected_children,
|
||||
item)) != NULL) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
return parent->connected_children.Count();
|
||||
}
|
||||
|
||||
|
||||
@@ -565,33 +551,29 @@ socket_set_max_backlog(net_socket *_socket, uint32 backlog)
|
||||
if (backlog > 256)
|
||||
backlog = 256;
|
||||
|
||||
mutex_lock(&socket->lock);
|
||||
MutexLocker _(socket->lock);
|
||||
|
||||
// first remove the pending connections, then the already connected
|
||||
// ones as needed
|
||||
net_socket_private* child;
|
||||
while (socket->child_count > backlog
|
||||
&& (child = (net_socket_private *)list_remove_tail_item(
|
||||
&socket->pending_children)) != NULL) {
|
||||
&& (child = socket->pending_children.RemoveTail()) != NULL) {
|
||||
child->parent = NULL;
|
||||
socket->child_count--;
|
||||
}
|
||||
while (socket->child_count > backlog
|
||||
&& (child = (net_socket_private *)list_remove_tail_item(
|
||||
&socket->connected_children)) != NULL) {
|
||||
&& (child = socket->connected_children.RemoveTail()) != NULL) {
|
||||
child->parent = NULL;
|
||||
socket_delete(child);
|
||||
socket->child_count--;
|
||||
}
|
||||
|
||||
socket->max_backlog = backlog;
|
||||
mutex_unlock(&socket->lock);
|
||||
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.
|
||||
*/
|
||||
status_t
|
||||
@@ -601,16 +583,15 @@ socket_connected(net_socket *socket)
|
||||
if (parent == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
mutex_lock(&parent->lock);
|
||||
MutexLocker _(&parent->lock);
|
||||
|
||||
list_remove_item(&parent->pending_children, socket);
|
||||
list_add_item(&parent->connected_children, socket);
|
||||
parent->pending_children.Remove((net_socket_private*)socket);
|
||||
parent->connected_children.Add((net_socket_private*)socket);
|
||||
|
||||
// notify parent
|
||||
if (parent->select_pool)
|
||||
notify_select_event_pool(parent->select_pool, B_SELECT_READ);
|
||||
|
||||
mutex_unlock(&parent->lock);
|
||||
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;
|
||||
|
||||
mutex_lock(&socket->lock);
|
||||
|
||||
status_t status = remove_select_sync_pool_entry(&socket->select_pool,
|
||||
sync, event);
|
||||
|
||||
mutex_unlock(&socket->lock);
|
||||
return status;
|
||||
MutexLocker _(socket->lock);
|
||||
return remove_select_sync_pool_entry(&socket->select_pool, sync, event);
|
||||
}
|
||||
|
||||
|
||||
@@ -685,14 +661,12 @@ socket_notify(net_socket *_socket, uint8 event, int32 value)
|
||||
|
||||
switch (event) {
|
||||
case B_SELECT_READ:
|
||||
if ((ssize_t)socket->receive.low_water_mark > value
|
||||
&& value >= B_OK)
|
||||
if ((ssize_t)socket->receive.low_water_mark > value && value >= B_OK)
|
||||
notify = false;
|
||||
break;
|
||||
|
||||
case B_SELECT_WRITE:
|
||||
if ((ssize_t)socket->send.low_water_mark > value
|
||||
&& value >= B_OK)
|
||||
if ((ssize_t)socket->send.low_water_mark > value && value >= B_OK)
|
||||
notify = false;
|
||||
break;
|
||||
|
||||
@@ -701,12 +675,11 @@ socket_notify(net_socket *_socket, uint8 event, int32 value)
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_lock(&socket->lock);
|
||||
MutexLocker _(socket->lock);
|
||||
|
||||
if (notify && socket->select_pool)
|
||||
notify_select_event_pool(socket->select_pool, event);
|
||||
|
||||
mutex_unlock(&socket->lock);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -1426,16 +1399,11 @@ socket_std_ops(int32 op, ...)
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
{
|
||||
// TODO: this is currently done in the net_stack driver
|
||||
// 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));
|
||||
new (&sSocketList) SocketList;
|
||||
mutex_init(&sSocketLock, "socket list");
|
||||
return B_OK;
|
||||
}
|
||||
case B_MODULE_UNINIT:
|
||||
//return put_module(NET_STARTER_MODULE_NAME);
|
||||
mutex_destroy(&sSocketLock);
|
||||
return B_OK;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user