mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 07:01:30 +00:00
[client] transport: make video waits cancellable
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "common/KVMFRRecovery.h"
|
||||
#include "common/LGMPConfig.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/event.h"
|
||||
#include "common/ivshmem.h"
|
||||
#include "common/locking.h"
|
||||
#include "common/option.h"
|
||||
@@ -78,6 +79,8 @@ struct LG_Transport
|
||||
LGMPInput * input;
|
||||
LG_Lock frameLock;
|
||||
LG_Lock pointerLock;
|
||||
LGEvent * frameWake;
|
||||
LGEvent * pointerWake;
|
||||
|
||||
unsigned cursorPollInterval;
|
||||
unsigned framePollInterval;
|
||||
@@ -345,6 +348,18 @@ static bool lgmp_create(LG_Transport ** result)
|
||||
this->framePollInterval = framePoll;
|
||||
this->cursorPollInterval = cursorPoll;
|
||||
|
||||
this->frameWake = lgCreateEvent(true, 0);
|
||||
this->pointerWake = lgCreateEvent(true, 0);
|
||||
if (!this->frameWake || !this->pointerWake)
|
||||
{
|
||||
if (this->frameWake)
|
||||
lgFreeEvent(this->frameWake);
|
||||
if (this->pointerWake)
|
||||
lgFreeEvent(this->pointerWake);
|
||||
free(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < LGMP_Q_FRAME_BUFFER_LEN; ++i)
|
||||
this->dma[i].fd = -1;
|
||||
|
||||
@@ -363,6 +378,8 @@ static bool lgmp_create(LG_Transport ** result)
|
||||
LG_LOCK_FREE(this->frameLock);
|
||||
LG_LOCK_FREE(this->pointerLock);
|
||||
LG_LOCK_FREE(this->recoveryLock);
|
||||
lgFreeEvent(this->frameWake);
|
||||
lgFreeEvent(this->pointerWake);
|
||||
free(this);
|
||||
return false;
|
||||
}
|
||||
@@ -399,6 +416,8 @@ static bool lgmp_create(LG_Transport ** result)
|
||||
LG_LOCK_FREE(this->frameLock);
|
||||
LG_LOCK_FREE(this->pointerLock);
|
||||
LG_LOCK_FREE(this->recoveryLock);
|
||||
lgFreeEvent(this->frameWake);
|
||||
lgFreeEvent(this->pointerWake);
|
||||
free(this);
|
||||
return false;
|
||||
}
|
||||
@@ -540,6 +559,8 @@ static void lgmp_destroy(LG_Transport ** transport)
|
||||
LG_LOCK_FREE(this->frameLock);
|
||||
LG_LOCK_FREE(this->pointerLock);
|
||||
LG_LOCK_FREE(this->recoveryLock);
|
||||
lgFreeEvent(this->frameWake);
|
||||
lgFreeEvent(this->pointerWake);
|
||||
free(this);
|
||||
*transport = NULL;
|
||||
}
|
||||
@@ -1087,8 +1108,25 @@ static LG_TransportStatus lgmp_subscribe(PLGMPClient client, uint32_t id,
|
||||
}
|
||||
}
|
||||
|
||||
static void lgmp_waitPoll(LGEvent * event, unsigned interval)
|
||||
{
|
||||
if (!interval)
|
||||
return;
|
||||
|
||||
const uint64_t timeout = (uint64_t)interval * 1000U;
|
||||
if (timeout < TIMEOUT_INFINITE)
|
||||
{
|
||||
lgWaitEventNS(event, (unsigned)timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned timeoutMS = interval / 1000U +
|
||||
(interval % 1000U != 0);
|
||||
lgWaitEvent(event, timeoutMS);
|
||||
}
|
||||
|
||||
static LG_TransportStatus lgmp_process(PLGMPClientQueue * subscription,
|
||||
unsigned interval, LGMPMessage * message)
|
||||
unsigned interval, LGEvent * wake, LGMPMessage * message)
|
||||
{
|
||||
PLGMPClientQueue queue = *subscription;
|
||||
if (!queue)
|
||||
@@ -1101,7 +1139,7 @@ static LG_TransportStatus lgmp_process(PLGMPClientQueue * subscription,
|
||||
return LG_TRANSPORT_OK;
|
||||
case LGMP_ERR_QUEUE_EMPTY:
|
||||
if (interval)
|
||||
usleep(interval);
|
||||
lgmp_waitPoll(wake, interval);
|
||||
return LG_TRANSPORT_TIMEOUT;
|
||||
case LGMP_ERR_QUEUE_TIMEOUT:
|
||||
case LGMP_ERR_QUEUE_UNSUBSCRIBED:
|
||||
@@ -1154,7 +1192,7 @@ static LG_TransportStatus lgmp_pollFrameQueue(
|
||||
}
|
||||
|
||||
const LG_TransportStatus status =
|
||||
lgmp_process(subscription, 0, &result->message);
|
||||
lgmp_process(subscription, 0, NULL, &result->message);
|
||||
if (status == LG_TRANSPORT_OK)
|
||||
{
|
||||
result->queue = queue;
|
||||
@@ -1581,10 +1619,15 @@ static LG_TransportStatus lgmp_nextFrame(LG_Transport * this, bool useDMA,
|
||||
LG_UNLOCK(this->frameLock);
|
||||
if ((status == LG_TRANSPORT_TIMEOUT ||
|
||||
status == LG_TRANSPORT_UNAVAILABLE) && this->framePollInterval)
|
||||
usleep(this->framePollInterval);
|
||||
lgmp_waitPoll(this->frameWake, this->framePollInterval);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void lgmp_cancelFrameWait(LG_Transport * this)
|
||||
{
|
||||
lgSignalEvent(this->frameWake);
|
||||
}
|
||||
|
||||
static bool lgmp_frameTimingReady(const KVMFRFrame * frame)
|
||||
{
|
||||
return __atomic_load_n(&frame->timingValid, __ATOMIC_ACQUIRE) &&
|
||||
@@ -1693,13 +1736,13 @@ static LG_TransportStatus lgmp_nextPointer(LG_Transport * this,
|
||||
pointerQueue = this->pointerQueue;
|
||||
LG_UNLOCK(this->pointerLock);
|
||||
if (status == LG_TRANSPORT_TIMEOUT)
|
||||
usleep(1000);
|
||||
lgmp_waitPoll(this->pointerWake, 1000);
|
||||
if (status == LG_TRANSPORT_OK)
|
||||
{
|
||||
LGMPMessage message;
|
||||
PLGMPClientQueue processedQueue = pointerQueue;
|
||||
status = lgmp_process(&processedQueue, this->cursorPollInterval,
|
||||
&message);
|
||||
this->pointerWake, &message);
|
||||
if (!processedQueue)
|
||||
lgmp_clearPointerQueue(this, pointerQueue);
|
||||
if (status == LG_TRANSPORT_OK)
|
||||
@@ -1785,6 +1828,11 @@ static LG_TransportStatus lgmp_nextPointer(LG_Transport * this,
|
||||
return LG_TRANSPORT_OK;
|
||||
}
|
||||
|
||||
static void lgmp_cancelPointerWait(LG_Transport * this)
|
||||
{
|
||||
lgSignalEvent(this->pointerWake);
|
||||
}
|
||||
|
||||
static void lgmp_releasePointer(LG_Transport * this,
|
||||
LG_TransportPointer * pointer)
|
||||
{
|
||||
@@ -1895,16 +1943,18 @@ static const LG_InputOps * lgmp_getInputOps(LG_Transport * this,
|
||||
|
||||
static const LG_FrameOps lgmpFrameOps =
|
||||
{
|
||||
.supportsDMA = lgmp_supportsDMA,
|
||||
.attachRenderer = lgmp_attachRenderer,
|
||||
.detachRenderer = lgmp_detachRenderer,
|
||||
.nextFrame = lgmp_nextFrame,
|
||||
.getFrameTiming = lgmp_getFrameTiming,
|
||||
.releaseFrame = lgmp_releaseFrame,
|
||||
.stopFrame = lgmp_stopFrame,
|
||||
.nextPointer = lgmp_nextPointer,
|
||||
.releasePointer = lgmp_releasePointer,
|
||||
.stopPointer = lgmp_stopPointer,
|
||||
.supportsDMA = lgmp_supportsDMA,
|
||||
.attachRenderer = lgmp_attachRenderer,
|
||||
.detachRenderer = lgmp_detachRenderer,
|
||||
.nextFrame = lgmp_nextFrame,
|
||||
.getFrameTiming = lgmp_getFrameTiming,
|
||||
.releaseFrame = lgmp_releaseFrame,
|
||||
.cancelFrameWait = lgmp_cancelFrameWait,
|
||||
.stopFrame = lgmp_stopFrame,
|
||||
.nextPointer = lgmp_nextPointer,
|
||||
.releasePointer = lgmp_releasePointer,
|
||||
.cancelPointerWait = lgmp_cancelPointerWait,
|
||||
.stopPointer = lgmp_stopPointer,
|
||||
};
|
||||
|
||||
static const LG_VideoOps lgmpVideoOps =
|
||||
|
||||
Reference in New Issue
Block a user