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,
const char* threadName,
const char* protocolName);
virtual status_t Stop();
protected:
bool _ResolveHostName(uint16_t port);
void _ProtocolSetup();
status_t _GetLine(BString& destString);
protected:
+1
View File
@@ -48,6 +48,7 @@ public:
protected:
static int32 _ThreadEntry(void* arg);
virtual void _ProtocolSetup() {};
virtual status_t _ProtocolLoop() = 0;
virtual void _EmitDebug(BUrlProtocolDebugMessage type,
const char* format, ...);
+1 -1
View File
@@ -219,7 +219,7 @@ BGopherRequest::Stop()
fSocket->Disconnect();
// 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();
// 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
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
BNetworkRequest::_GetLine(BString& destString)
{
+2 -21
View File
@@ -87,12 +87,8 @@ BUrlRequest::Stop()
if (!fRunning)
return B_ERROR;
status_t threadStatus = B_OK;
fQuit = true;
send_signal(fThreadId, SIGUSR1); // unblock blocking syscalls.
wait_for_thread(fThreadId, &threadStatus);
return threadStatus;
return B_OK;
}
@@ -184,27 +180,12 @@ BUrlRequest::Status() const
// #pragma mark Thread management
static void
empty(int)
{
}
/*static*/ int32
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);
request->fThreadStatus = B_BUSY;
request->_ProtocolSetup();
status_t protocolLoopExitStatus = request->_ProtocolLoop();