* 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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user