Move signal hack to BNetworkRequest

* This is used to unlock sockets when a read is pending after a close
* It is not needed on requests that don't use a socket.
This commit is contained in:
Adrien Destugues
2014-08-04 16:25:48 +02:00
parent 2f9b187497
commit 89b4e98a8f
6 changed files with 44 additions and 23 deletions
+4
View File
@@ -22,9 +22,13 @@ public:
BUrlContext* context, BUrlContext* context,
const char* threadName, const char* threadName,
const char* protocolName); const char* protocolName);
virtual status_t Stop();
protected: protected:
bool _ResolveHostName(uint16_t port); bool _ResolveHostName(uint16_t port);
void _ProtocolSetup();
status_t _GetLine(BString& destString); status_t _GetLine(BString& destString);
protected: protected:
+1
View File
@@ -48,6 +48,7 @@ public:
protected: protected:
static int32 _ThreadEntry(void* arg); static int32 _ThreadEntry(void* arg);
virtual void _ProtocolSetup() {};
virtual status_t _ProtocolLoop() = 0; virtual status_t _ProtocolLoop() = 0;
virtual void _EmitDebug(BUrlProtocolDebugMessage type, virtual void _EmitDebug(BUrlProtocolDebugMessage type,
const char* format, ...); const char* format, ...);
+1 -1
View File
@@ -219,7 +219,7 @@ BGopherRequest::Stop()
fSocket->Disconnect(); fSocket->Disconnect();
// Unlock any pending connect, read or write operation. // Unlock any pending connect, read or write operation.
} }
return BUrlRequest::Stop(); return BNetworkRequest::Stop();
} }
+1 -1
View File
@@ -278,7 +278,7 @@ BHttpRequest::Stop()
fSocket->Disconnect(); fSocket->Disconnect();
// Unlock any pending connect, read or write operation. // Unlock any pending connect, read or write operation.
} }
return BUrlRequest::Stop(); return BNetworkRequest::Stop();
} }
@@ -21,6 +21,20 @@ BNetworkRequest::BNetworkRequest(const BUrl& url, BUrlProtocolListener* listener
} }
status_t
BNetworkRequest::Stop()
{
status_t threadStatus = BUrlRequest::Stop();
if (threadStatus != B_OK)
return threadStatus;
send_signal(fThreadId, SIGUSR1); // unblock blocking syscalls.
wait_for_thread(fThreadId, &threadStatus);
return threadStatus;
}
bool bool
BNetworkRequest::_ResolveHostName(uint16_t port) BNetworkRequest::_ResolveHostName(uint16_t port)
{ {
@@ -48,6 +62,27 @@ BNetworkRequest::_ResolveHostName(uint16_t port)
} }
static void
empty(int)
{
}
void
BNetworkRequest::_ProtocolSetup()
{
// Setup an (empty) signal handler so we can be stopped by a signal,
// without the whole process being killed.
// TODO make connect() properly unlock when close() is called on the
// socket, and remove this.
struct sigaction action;
action.sa_handler = empty;
action.sa_mask = 0;
action.sa_flags = 0;
sigaction(SIGUSR1, &action, NULL);
}
status_t status_t
BNetworkRequest::_GetLine(BString& destString) BNetworkRequest::_GetLine(BString& destString)
{ {
+2 -21
View File
@@ -87,12 +87,8 @@ BUrlRequest::Stop()
if (!fRunning) if (!fRunning)
return B_ERROR; return B_ERROR;
status_t threadStatus = B_OK;
fQuit = true; fQuit = true;
return B_OK;
send_signal(fThreadId, SIGUSR1); // unblock blocking syscalls.
wait_for_thread(fThreadId, &threadStatus);
return threadStatus;
} }
@@ -184,27 +180,12 @@ BUrlRequest::Status() const
// #pragma mark Thread management // #pragma mark Thread management
static void
empty(int)
{
}
/*static*/ int32 /*static*/ int32
BUrlRequest::_ThreadEntry(void* arg) BUrlRequest::_ThreadEntry(void* arg)
{ {
// Setup an (empty) signal handler so we can be stopped by a signal,
// without the whole process being killed.
// TODO make connect() properly unlock when close() is called on the
// socket, and remove this.
struct sigaction action;
action.sa_handler = empty;
action.sa_mask = 0;
action.sa_flags = 0;
sigaction(SIGUSR1, &action, NULL);
BUrlRequest* request = reinterpret_cast<BUrlRequest*>(arg); BUrlRequest* request = reinterpret_cast<BUrlRequest*>(arg);
request->fThreadStatus = B_BUSY; request->fThreadStatus = B_BUSY;
request->_ProtocolSetup();
status_t protocolLoopExitStatus = request->_ProtocolLoop(); status_t protocolLoopExitStatus = request->_ProtocolLoop();