* net_socket_module_info::acquire_socket() now returns whether or not the

socket could be acquired, ie. when its reference count is 0, it cannot be
  acquired anymore. This requires the protocol to do proper locking, though.
* The TCP EndpointManager now checks the return value of acquire_socket(), and
  only returns the endpoint if that succeeded.
* This fixes bug #2197.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30363 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-04-24 10:12:30 +00:00
parent c9928eb11a
commit 6f440aed2c
4 changed files with 19 additions and 10 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ struct net_socket_module_info {
struct net_stat *stat); struct net_stat *stat);
// connections // connections
void (*acquire_socket)(net_socket *socket); bool (*acquire_socket)(net_socket *socket);
bool (*release_socket)(net_socket *socket); bool (*release_socket)(net_socket *socket);
status_t (*spawn_pending_socket)(net_socket *parent, status_t (*spawn_pending_socket)(net_socket *parent,
@@ -320,8 +320,8 @@ EndpointManager::FindConnection(sockaddr* local, sockaddr* peer)
if (endpoint != NULL) { if (endpoint != NULL) {
TRACE(("TCP: Received packet corresponds to explicit endpoint %p\n", TRACE(("TCP: Received packet corresponds to explicit endpoint %p\n",
endpoint)); endpoint));
gSocketModule->acquire_socket(endpoint->socket); if (gSocketModule->acquire_socket(endpoint->socket))
return endpoint; return endpoint;
} }
// no explicit endpoint exists, check for wildcard endpoints // no explicit endpoint exists, check for wildcard endpoints
@@ -333,8 +333,8 @@ EndpointManager::FindConnection(sockaddr* local, sockaddr* peer)
if (endpoint != NULL) { if (endpoint != NULL) {
TRACE(("TCP: Received packet corresponds to wildcard endpoint %p\n", TRACE(("TCP: Received packet corresponds to wildcard endpoint %p\n",
endpoint)); endpoint));
gSocketModule->acquire_socket(endpoint->socket); if (gSocketModule->acquire_socket(endpoint->socket))
return endpoint; return endpoint;
} }
SocketAddressStorage localWildcard(AddressModule()); SocketAddressStorage localWildcard(AddressModule());
@@ -345,8 +345,8 @@ EndpointManager::FindConnection(sockaddr* local, sockaddr* peer)
if (endpoint != NULL) { if (endpoint != NULL) {
TRACE(("TCP: Received packet corresponds to local wildcard endpoint " TRACE(("TCP: Received packet corresponds to local wildcard endpoint "
"%p\n", endpoint)); "%p\n", endpoint));
gSocketModule->acquire_socket(endpoint->socket); if (gSocketModule->acquire_socket(endpoint->socket))
return endpoint; return endpoint;
} }
// no matching endpoint exists // no matching endpoint exists
@@ -673,7 +673,7 @@ TCPEndpoint::Accept(struct net_socket** _acceptedSocket)
status = acquire_sem_etc(fAcceptSemaphore, 1, B_ABSOLUTE_TIMEOUT status = acquire_sem_etc(fAcceptSemaphore, 1, B_ABSOLUTE_TIMEOUT
| B_CAN_INTERRUPT, timeout); | B_CAN_INTERRUPT, timeout);
if (status < B_OK) if (status != B_OK)
return status; return status;
locker.Lock(); locker.Lock();
@@ -682,7 +682,7 @@ TCPEndpoint::Accept(struct net_socket** _acceptedSocket)
if (status == B_OK) if (status == B_OK)
TRACE(" Accept() returning %p", (*_acceptedSocket)->first_protocol); TRACE(" Accept() returning %p", (*_acceptedSocket)->first_protocol);
#endif #endif
} while (status < B_OK); } while (status != B_OK);
return status; return status;
} }
@@ -598,11 +598,20 @@ socket_get_next_stat(uint32* _cookie, int family, struct net_stat* stat)
// #pragma mark - connections // #pragma mark - connections
void bool
socket_acquire(net_socket* _socket) socket_acquire(net_socket* _socket)
{ {
net_socket_private* socket = (net_socket_private*)_socket; net_socket_private* socket = (net_socket_private*)_socket;
// During destruction, the socket might still be accessible over its endpoint
// protocol. We need to make sure the endpoint cannot acquire the socket
// anymore -- while not obvious, the endpoint protocol is responsible for the
// proper locking here.
if (socket->CountReferences() == 0)
return false;
socket->AddReference(); socket->AddReference();
return true;
} }