nfs4: Fix callback connection closing

This commit is contained in:
Pawel Dziepak
2012-08-07 00:56:15 +02:00
parent 49935f9b4f
commit d8e2263f3b
3 changed files with 15 additions and 2 deletions
@@ -163,7 +163,7 @@ ServerAddress::InAddr() const
status_t status_t
ServerAddress::ResolveName(const char* name, ServerAddress* address) ServerAddress::ResolveName(const char* name, ServerAddress* address)
{ {
address->fProtocol = IPPROTO_UDP; address->fProtocol = IPPROTO_TCP;
// getaddrinfo() is very expensive when called from kernel, so we do not // getaddrinfo() is very expensive when called from kernel, so we do not
// want to call it unless there is no other choice. // want to call it unless there is no other choice.
@@ -143,6 +143,10 @@ CallbackServer::StopServer()
ConnectionEntry* entry = fConnectionList; ConnectionEntry* entry = fConnectionList;
fConnectionList = entry->fNext; fConnectionList = entry->fNext;
entry->fConnection->Disconnect(); entry->fConnection->Disconnect();
status_t result;
wait_for_thread(entry->fThread, &result);
delete entry->fConnection; delete entry->fConnection;
delete entry; delete entry;
} }
@@ -163,6 +167,8 @@ CallbackServer::NewConnection(Connection* connection)
MutexLocker locker(fConnectionLock); MutexLocker locker(fConnectionLock);
entry->fNext = fConnectionList; entry->fNext = fConnectionList;
if (fConnectionList != NULL)
fConnectionList->fPrev = entry;
fConnectionList = entry; fConnectionList = entry;
locker.Unlock(); locker.Unlock();
@@ -177,13 +183,17 @@ CallbackServer::NewConnection(Connection* connection)
thread = spawn_kernel_thread(&CallbackServer::ConnectionThreadLauncher, thread = spawn_kernel_thread(&CallbackServer::ConnectionThreadLauncher,
"NFSv4 Callback Connection", B_NORMAL_PRIORITY, arguments); "NFSv4 Callback Connection", B_NORMAL_PRIORITY, arguments);
if (thread < B_OK) { if (thread < B_OK) {
ReleaseConnection(entry);
free(arguments); free(arguments);
return thread; return thread;
} }
entry->fThread = thread;
status_t result = resume_thread(thread); status_t result = resume_thread(thread);
if (result != B_OK) { if (result != B_OK) {
kill_thread(thread); kill_thread(thread);
ReleaseConnection(entry);
free(arguments); free(arguments);
return result; return result;
} }
@@ -232,7 +242,8 @@ CallbackServer::ConnectionThread(ConnectionEntry* entry)
void* buffer; void* buffer;
status_t result = connection->Receive(&buffer, &size); status_t result = connection->Receive(&buffer, &size);
if (result != B_OK) { if (result != B_OK) {
ReleaseConnection(entry); if (result != ECONNABORTED)
ReleaseConnection(entry);
return result; return result;
} }
@@ -20,6 +20,8 @@ class Callback;
struct ConnectionEntry { struct ConnectionEntry {
Connection* fConnection; Connection* fConnection;
thread_id fThread;
ConnectionEntry* fNext; ConnectionEntry* fNext;
ConnectionEntry* fPrev; ConnectionEntry* fPrev;
}; };