* 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);
// connections
void (*acquire_socket)(net_socket *socket);
bool (*acquire_socket)(net_socket *socket);
bool (*release_socket)(net_socket *socket);
status_t (*spawn_pending_socket)(net_socket *parent,
@@ -320,8 +320,8 @@ EndpointManager::FindConnection(sockaddr* local, sockaddr* peer)
if (endpoint != NULL) {
TRACE(("TCP: Received packet corresponds to explicit endpoint %p\n",
endpoint));
gSocketModule->acquire_socket(endpoint->socket);
return endpoint;
if (gSocketModule->acquire_socket(endpoint->socket))
return endpoint;
}
// no explicit endpoint exists, check for wildcard endpoints
@@ -333,8 +333,8 @@ EndpointManager::FindConnection(sockaddr* local, sockaddr* peer)
if (endpoint != NULL) {
TRACE(("TCP: Received packet corresponds to wildcard endpoint %p\n",
endpoint));
gSocketModule->acquire_socket(endpoint->socket);
return endpoint;
if (gSocketModule->acquire_socket(endpoint->socket))
return endpoint;
}
SocketAddressStorage localWildcard(AddressModule());
@@ -345,8 +345,8 @@ EndpointManager::FindConnection(sockaddr* local, sockaddr* peer)
if (endpoint != NULL) {
TRACE(("TCP: Received packet corresponds to local wildcard endpoint "
"%p\n", endpoint));
gSocketModule->acquire_socket(endpoint->socket);
return endpoint;
if (gSocketModule->acquire_socket(endpoint->socket))
return endpoint;
}
// no matching endpoint exists
@@ -673,7 +673,7 @@ TCPEndpoint::Accept(struct net_socket** _acceptedSocket)
status = acquire_sem_etc(fAcceptSemaphore, 1, B_ABSOLUTE_TIMEOUT
| B_CAN_INTERRUPT, timeout);
if (status < B_OK)
if (status != B_OK)
return status;
locker.Lock();
@@ -682,7 +682,7 @@ TCPEndpoint::Accept(struct net_socket** _acceptedSocket)
if (status == B_OK)
TRACE(" Accept() returning %p", (*_acceptedSocket)->first_protocol);
#endif
} while (status < B_OK);
} while (status != B_OK);
return status;
}
@@ -598,11 +598,20 @@ socket_get_next_stat(uint32* _cookie, int family, struct net_stat* stat)
// #pragma mark - connections
void
bool
socket_acquire(net_socket* _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();
return true;
}