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