mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 00:31:31 +00:00
[client] lgmp: serialize stale pointer recovery
Clear timed-out pointer subscriptions under pointerLock so control sends cannot race a cached queue handle becoming NULL.
This commit is contained in:
@@ -651,20 +651,30 @@ static LG_TransportStatus lgmp_doneFrameMessage(
|
|||||||
return LG_TRANSPORT_ERROR;
|
return LG_TRANSPORT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LG_TransportStatus lgmp_donePointerMessage(LG_Transport * this)
|
static void lgmp_clearPointerQueue(LG_Transport * this,
|
||||||
|
PLGMPClientQueue expected)
|
||||||
{
|
{
|
||||||
const LGMP_STATUS status = lgmpClientMessageDone(this->pointerQueue);
|
LG_LOCK(this->pointerLock);
|
||||||
|
if (this->pointerQueue == expected)
|
||||||
|
this->pointerQueue = NULL;
|
||||||
|
LG_UNLOCK(this->pointerLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LG_TransportStatus lgmp_donePointerMessage(LG_Transport * this,
|
||||||
|
PLGMPClientQueue queue)
|
||||||
|
{
|
||||||
|
const LGMP_STATUS status = lgmpClientMessageDone(queue);
|
||||||
if (status == LGMP_OK)
|
if (status == LGMP_OK)
|
||||||
return LG_TRANSPORT_OK;
|
return LG_TRANSPORT_OK;
|
||||||
if (status == LGMP_ERR_INVALID_SESSION)
|
if (status == LGMP_ERR_INVALID_SESSION)
|
||||||
{
|
{
|
||||||
this->pointerQueue = NULL;
|
lgmp_clearPointerQueue(this, queue);
|
||||||
return LG_TRANSPORT_DISCONNECTED;
|
return LG_TRANSPORT_DISCONNECTED;
|
||||||
}
|
}
|
||||||
if (status == LGMP_ERR_QUEUE_TIMEOUT ||
|
if (status == LGMP_ERR_QUEUE_TIMEOUT ||
|
||||||
status == LGMP_ERR_QUEUE_UNSUBSCRIBED)
|
status == LGMP_ERR_QUEUE_UNSUBSCRIBED)
|
||||||
{
|
{
|
||||||
this->pointerQueue = NULL;
|
lgmp_clearPointerQueue(this, queue);
|
||||||
return LG_TRANSPORT_OK;
|
return LG_TRANSPORT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1090,29 +1100,35 @@ static LG_TransportStatus lgmp_nextPointer(LG_Transport * this,
|
|||||||
if (!this->connected)
|
if (!this->connected)
|
||||||
return LG_TRANSPORT_DISCONNECTED;
|
return LG_TRANSPORT_DISCONNECTED;
|
||||||
|
|
||||||
uint32_t pointerFlags = 0;
|
uint32_t pointerFlags = 0;
|
||||||
size_t shapeSize = 0;
|
size_t shapeSize = 0;
|
||||||
size_t transformSize = 0;
|
size_t transformSize = 0;
|
||||||
LG_TransportStatus status = LG_TRANSPORT_OK;
|
LG_TransportStatus status = LG_TRANSPORT_OK;
|
||||||
|
PLGMPClientQueue pointerQueue;
|
||||||
|
LG_LOCK(this->pointerLock);
|
||||||
if (!this->pointerQueue)
|
if (!this->pointerQueue)
|
||||||
{
|
{
|
||||||
LG_LOCK(this->pointerLock);
|
|
||||||
status = lgmp_subscribe(this->client, LGMP_Q_POINTER,
|
status = lgmp_subscribe(this->client, LGMP_Q_POINTER,
|
||||||
&this->pointerQueue);
|
&this->pointerQueue);
|
||||||
LG_UNLOCK(this->pointerLock);
|
|
||||||
if (status == LG_TRANSPORT_TIMEOUT)
|
|
||||||
usleep(1000);
|
|
||||||
}
|
}
|
||||||
|
pointerQueue = this->pointerQueue;
|
||||||
|
LG_UNLOCK(this->pointerLock);
|
||||||
|
if (status == LG_TRANSPORT_TIMEOUT)
|
||||||
|
usleep(1000);
|
||||||
if (status == LG_TRANSPORT_OK)
|
if (status == LG_TRANSPORT_OK)
|
||||||
{
|
{
|
||||||
LGMPMessage message;
|
LGMPMessage message;
|
||||||
status = lgmp_process(&this->pointerQueue, this->cursorPollInterval,
|
PLGMPClientQueue processedQueue = pointerQueue;
|
||||||
|
status = lgmp_process(&processedQueue, this->cursorPollInterval,
|
||||||
&message);
|
&message);
|
||||||
|
if (!processedQueue)
|
||||||
|
lgmp_clearPointerQueue(this, pointerQueue);
|
||||||
if (status == LG_TRANSPORT_OK)
|
if (status == LG_TRANSPORT_OK)
|
||||||
{
|
{
|
||||||
if (message.size < sizeof(KVMFRCursor))
|
if (message.size < sizeof(KVMFRCursor))
|
||||||
{
|
{
|
||||||
const LG_TransportStatus done = lgmp_donePointerMessage(this);
|
const LG_TransportStatus done =
|
||||||
|
lgmp_donePointerMessage(this, pointerQueue);
|
||||||
status = done == LG_TRANSPORT_DISCONNECTED ?
|
status = done == LG_TRANSPORT_DISCONNECTED ?
|
||||||
done : LG_TRANSPORT_ERROR;
|
done : LG_TRANSPORT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1127,7 +1143,8 @@ static LG_TransportStatus lgmp_nextPointer(LG_Transport * this,
|
|||||||
if (shapeSize > message.size - sizeof(*cursor) ||
|
if (shapeSize > message.size - sizeof(*cursor) ||
|
||||||
transformSize > message.size - sizeof(*cursor) - shapeSize)
|
transformSize > message.size - sizeof(*cursor) - shapeSize)
|
||||||
{
|
{
|
||||||
const LG_TransportStatus done = lgmp_donePointerMessage(this);
|
const LG_TransportStatus done =
|
||||||
|
lgmp_donePointerMessage(this, pointerQueue);
|
||||||
status = done == LG_TRANSPORT_DISCONNECTED ?
|
status = done == LG_TRANSPORT_DISCONNECTED ?
|
||||||
done : LG_TRANSPORT_ERROR;
|
done : LG_TRANSPORT_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1150,7 +1167,8 @@ static LG_TransportStatus lgmp_nextPointer(LG_Transport * this,
|
|||||||
memcpy(this->pointerData, message.mem, needed);
|
memcpy(this->pointerData, message.mem, needed);
|
||||||
pointerFlags = (uint32_t)message.udata;
|
pointerFlags = (uint32_t)message.udata;
|
||||||
}
|
}
|
||||||
const LG_TransportStatus done = lgmp_donePointerMessage(this);
|
const LG_TransportStatus done =
|
||||||
|
lgmp_donePointerMessage(this, pointerQueue);
|
||||||
if (status == LG_TRANSPORT_OK)
|
if (status == LG_TRANSPORT_OK)
|
||||||
status = done;
|
status = done;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user