SocketAPI OSX: Forbid further sends on connectionDidDie

Also release the remote end immediately.
This commit is contained in:
Christian Kamm 2019-01-17 10:16:44 +01:00 committed by Kevin Ottens
parent 6f4bf585f0
commit 0eebd77d2c
No known key found for this signature in database
GPG key ID: 074BBBCB8DECC9E2

View file

@ -42,9 +42,13 @@ public:
SocketApiSocketPrivate(NSDistantObject <ChannelProtocol> *remoteEnd); SocketApiSocketPrivate(NSDistantObject <ChannelProtocol> *remoteEnd);
~SocketApiSocketPrivate(); ~SocketApiSocketPrivate();
// release remoteEnd
void disconnectRemote();
NSDistantObject <ChannelProtocol> *remoteEnd; NSDistantObject <ChannelProtocol> *remoteEnd;
LocalEnd *localEnd; LocalEnd *localEnd;
QByteArray inBuffer; QByteArray inBuffer;
bool isRemoteDisconnected = false;
}; };
class SocketApiServerPrivate class SocketApiServerPrivate
@ -80,8 +84,10 @@ public:
- (void)connectionDidDie:(NSNotification*)notification - (void)connectionDidDie:(NSNotification*)notification
{ {
#pragma unused(notification) #pragma unused(notification)
if (_wrapper) if (_wrapper) {
_wrapper->disconnectRemote();
emit _wrapper->q_ptr->disconnected(); emit _wrapper->q_ptr->disconnected();
}
} }
@end @end
@ -133,8 +139,11 @@ qint64 SocketApiSocket::readData(char *data, qint64 maxlen)
qint64 SocketApiSocket::writeData(const char *data, qint64 len) qint64 SocketApiSocket::writeData(const char *data, qint64 len)
{ {
Q_D(SocketApiSocket);
if (d->isRemoteDisconnected)
return -1;
@try { @try {
Q_D(SocketApiSocket);
// FIXME: The NSConnection will make this block unless the function is marked as "oneway" // FIXME: The NSConnection will make this block unless the function is marked as "oneway"
// in the protocol. This isn't async and reduces our performances but this currectly avoids // in the protocol. This isn't async and reduces our performances but this currectly avoids
// a Mach queue deadlock during requests bursts of the legacy OwnCloudFinder extension. // a Mach queue deadlock during requests bursts of the legacy OwnCloudFinder extension.
@ -143,6 +152,7 @@ qint64 SocketApiSocket::writeData(const char *data, qint64 len)
return len; return len;
} @catch(NSException* e) { } @catch(NSException* e) {
// connectionDidDie can be notified too late, also interpret any sending exception as a disconnection. // connectionDidDie can be notified too late, also interpret any sending exception as a disconnection.
d->disconnectRemote();
emit disconnected(); emit disconnected();
return -1; return -1;
} }
@ -174,12 +184,22 @@ SocketApiSocketPrivate::SocketApiSocketPrivate(NSDistantObject <ChannelProtocol>
SocketApiSocketPrivate::~SocketApiSocketPrivate() SocketApiSocketPrivate::~SocketApiSocketPrivate()
{ {
[remoteEnd release]; disconnectRemote();
// The DO vended localEnd might still be referenced by the connection // The DO vended localEnd might still be referenced by the connection
localEnd.wrapper = nil; localEnd.wrapper = nil;
[localEnd release]; [localEnd release];
} }
void SocketApiSocketPrivate::disconnectRemote()
{
if (isRemoteDisconnected)
return;
isRemoteDisconnected = true;
[remoteEnd release];
}
SocketApiServer::SocketApiServer() SocketApiServer::SocketApiServer()
: d_ptr(new SocketApiServerPrivate) : d_ptr(new SocketApiServerPrivate)
{ {