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();
// release remoteEnd
void disconnectRemote();
NSDistantObject <ChannelProtocol> *remoteEnd;
LocalEnd *localEnd;
QByteArray inBuffer;
bool isRemoteDisconnected = false;
};
class SocketApiServerPrivate
@ -80,8 +84,10 @@ public:
- (void)connectionDidDie:(NSNotification*)notification
{
#pragma unused(notification)
if (_wrapper)
if (_wrapper) {
_wrapper->disconnectRemote();
emit _wrapper->q_ptr->disconnected();
}
}
@end
@ -133,8 +139,11 @@ qint64 SocketApiSocket::readData(char *data, qint64 maxlen)
qint64 SocketApiSocket::writeData(const char *data, qint64 len)
{
Q_D(SocketApiSocket);
if (d->isRemoteDisconnected)
return -1;
@try {
Q_D(SocketApiSocket);
// 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
// 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;
} @catch(NSException* e) {
// connectionDidDie can be notified too late, also interpret any sending exception as a disconnection.
d->disconnectRemote();
emit disconnected();
return -1;
}
@ -174,12 +184,22 @@ SocketApiSocketPrivate::SocketApiSocketPrivate(NSDistantObject <ChannelProtocol>
SocketApiSocketPrivate::~SocketApiSocketPrivate()
{
[remoteEnd release];
disconnectRemote();
// The DO vended localEnd might still be referenced by the connection
localEnd.wrapper = nil;
[localEnd release];
}
void SocketApiSocketPrivate::disconnectRemote()
{
if (isRemoteDisconnected)
return;
isRemoteDisconnected = true;
[remoteEnd release];
}
SocketApiServer::SocketApiServer()
: d_ptr(new SocketApiServerPrivate)
{