1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2026-02-09 13:10:38 +00:00

1. Replaced semaphore in readableStream with spin lock

2. Updated WebRTC Consent Freshness behavior to take into account dTLS traffic
This commit is contained in:
Bryan Roe
2020-11-30 11:48:09 -08:00
parent 77834337fd
commit 78c553d3ad
3 changed files with 33 additions and 20 deletions

View File

@@ -189,24 +189,24 @@ int ILibDuktape_readableStream_WriteData_Flush(struct ILibDuktape_WritableStream
{
ILibDuktape_readableStream *stream = (ILibDuktape_readableStream*)user;
int unpipeInProgress = 0;
#ifdef WIN32
if(InterlockedDecrement(&(stream->pipe_pendingCount)) == 0)
#elif defined(__ATOMIC_SEQ_CST)
if (__atomic_sub_fetch(&(stream->pipe_pendingCount), 1, __ATOMIC_SEQ_CST) == 0)
#else
sem_wait(&(stream->pipeLock));
ILibSpinLock_Lock(&(stream->pipeLock));
--stream->pipe_pendingCount;
sem_post(&(stream->pipeLock));
ILibSpinLock_UnLock(&(stream->pipeLock));
if(stream->pipe_pendingCount == 0)
#endif
{
if (stream->emitter->ctx == NULL) { return(1); }
sem_wait(&(stream->pipeLock));
ILibSpinLock_Lock(&(stream->pipeLock));
stream->pipeInProgress = 0;
unpipeInProgress = stream->unpipeInProgress;
sem_post(&(stream->pipeLock));
ILibSpinLock_UnLock(&(stream->pipeLock));
if (stream->paused != 0 && stream->paused_data != NULL)
{
@@ -311,9 +311,9 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
if (stream->bypassValue == 0 || stream->bypassValue != streamReserved)
{
sem_wait(&(stream->pipeLock));
ILibSpinLock_Lock(&(stream->pipeLock));
stream->pipeInProgress = 1;
sem_post(&(stream->pipeLock));
ILibSpinLock_UnLock(&(stream->pipeLock));
w = stream->nextWriteable;
stream->pipe_pendingCount = 0;
@@ -383,9 +383,9 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
if (dispatched == 0)
{
sem_wait(&(stream->pipeLock));
ILibSpinLock_Lock(&(stream->pipeLock));
stream->pipeInProgress = 0;
sem_post(&(stream->pipeLock));
ILibSpinLock_UnLock(&(stream->pipeLock));
if(ILibDuktape_EventEmitter_HasListeners(stream->emitter, "data"))
{
@@ -622,7 +622,7 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
rstream = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop_2(ctx); // ...
sem_wait(&(rstream->pipeLock));
ILibSpinLock_Lock(&(rstream->pipeLock));
if (rstream->pipeInProgress != 0)
{
// We must YIELD and try again later, becuase there is an active dispatch going on
@@ -636,7 +636,7 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
duk_put_prop_string(ctx, -2, "opt");
}
duk_dup(ctx, 0);
sem_post(&(rstream->pipeLock));
ILibSpinLock_UnLock(&(rstream->pipeLock));
return(1);
}
else
@@ -682,7 +682,7 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
rstream->bypassValue = Duktape_GetIntPropertyValue(ctx, 1, "dataTypeSkip", 0);
rstream->noPropagateEnd = Duktape_GetBooleanProperty(ctx, 1, "end", 1) == 0 ? 1 : 0;
}
sem_post(&(rstream->pipeLock));
ILibSpinLock_UnLock(&(rstream->pipeLock));
// Now we need to emit a 'pipe' event on the writable that we just attached
duk_push_heapptr(ctx, w->writableStream); // [dest]
@@ -723,7 +723,7 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
duk_pop_2(ctx); // ...
if (data->emitter->ctx == NULL) { return; }
sem_wait(&(data->pipeLock));
ILibSpinLock_Lock(&(data->pipeLock));
if (data->pipeInProgress != 0)
{
// We must yield, and try again, because there's an active dispatch going on
@@ -733,7 +733,7 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
duk_put_prop_string(ctx, -2, "\xFF_Self"); // [immediate]
if (argsLen > 1 && args[1] != NULL) { duk_push_heapptr(ctx, args[1]); duk_put_prop_string(ctx, -2, "\xFF_w"); }
duk_pop(ctx); // ...
sem_post(&(data->pipeLock));
ILibSpinLock_UnLock(&(data->pipeLock));
return;
}
else
@@ -818,7 +818,7 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
}
}
data->unpipeInProgress = 0;
sem_post(&(data->pipeLock));
ILibSpinLock_UnLock(&(data->pipeLock));
}
duk_ret_t ILibDuktape_readableStream_unpipe(duk_context *ctx)
{
@@ -834,7 +834,7 @@ duk_ret_t ILibDuktape_readableStream_unpipe(duk_context *ctx)
if (data->emitter->ctx == NULL) { return(0); }
sem_wait(&(data->pipeLock));
ILibSpinLock_Lock(&(data->pipeLock));
data->unpipeInProgress = 1;
if (nargs == 1 && duk_is_object(ctx, 0))
{
@@ -851,7 +851,7 @@ duk_ret_t ILibDuktape_readableStream_unpipe(duk_context *ctx)
if (onlyItem && wcount > 1) { onlyItem = 0; }
duk_pop_2(ctx); // [readable]
}
sem_post(&(data->pipeLock));
ILibSpinLock_UnLock(&(data->pipeLock));
if (duk_ctx_shutting_down(ctx) == 0)
{
@@ -921,7 +921,6 @@ duk_ret_t ILibDuktape_ReadableStream_PipeLockFinalizer(duk_context *ctx)
ptrs->paused_data = tmp;
}
sem_destroy(&(ptrs->pipeLock));
duk_pop_2(ctx);
return(0);
}
@@ -973,7 +972,7 @@ ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx,
retVal->PauseHandler = OnPause;
retVal->ResumeHandler = OnResume;
retVal->UnshiftHandler = OnUnshift;
sem_init(&(retVal->pipeLock), 0, 1);
ILibSpinLock_Init(&(retVal->pipeLock));
ILibDuktape_CreateFinalizerEx(ctx, ILibDuktape_ReadableStream_PipeLockFinalizer, 1);
retVal->emitter = emitter = ILibDuktape_EventEmitter_Create(ctx);

View File

@@ -44,7 +44,7 @@ typedef struct ILibDuktape_readableStream
void *user;
void *pipeArray;
ILibDuktape_readableStream_nextWriteablePipe *nextWriteable;
sem_t pipeLock;
ILibSpinLock pipeLock;
#if defined(WIN32)
volatile LONG pipe_pendingCount; // Use Windows Built-in Atomic Intrinsics
#elif defined(__ATOMIC_SEQ_CST)

View File

@@ -2301,6 +2301,7 @@ int ILibStun_ProcessStunPacket(void *j, char* buffer, int bufferLength, struct s
processed = 1;
// We got a response, so we can reset the timer for Freshness
obj->dTlsSessions[SessionSlot]->freshnessTimestampStart = 0;
ILibLifeTime_Remove(obj->Timer, ILibWebRTC_DTLS_TO_CONSENT_FRESHNESS_TIMER_OBJECT(obj->dTlsSessions[SessionSlot]));
ILibLifeTime_Add(obj->Timer, ILibWebRTC_DTLS_TO_CONSENT_FRESHNESS_TIMER_OBJECT(obj->dTlsSessions[SessionSlot]), ILibStun_MaxConsentFreshnessTimeoutSeconds, ILibStun_WebRTC_ConsentFreshness_Start, NULL);
}
@@ -4253,6 +4254,18 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
crc = ((unsigned int*)buffer)[2];
((unsigned int*)buffer)[2] = 0;
if (crc != crc32c(0, (unsigned char*)buffer, (uint32_t)bufferLength)) return;
if (o->freshnessTimestampStart != 0)
{
// Technically speaking, consent freshness is supposed to be independent of SCTP/DTLS, but Chromium and Firefox no longer
// respond to a freshness probe, so I have to work-around this issue
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_DTLS, ILibRemoteLogging_Flags_VerbosityLevel_2, "Consent Freshness Updated (via dTLS) on IceSlot: %d", session);
o->freshnessTimestampStart = 0;
ILibLifeTime_Remove(obj->Timer, ILibWebRTC_DTLS_TO_CONSENT_FRESHNESS_TIMER_OBJECT(o));
ILibLifeTime_Add(obj->Timer, ILibWebRTC_DTLS_TO_CONSENT_FRESHNESS_TIMER_OBJECT(o), ILibStun_MaxConsentFreshnessTimeoutSeconds, ILibStun_WebRTC_ConsentFreshness_Start, NULL);
}
sem_wait(&(o->Lock));
// Decode the rest of the header
@@ -5819,6 +5832,7 @@ void ILibStun_DTLS_Success(struct ILibStun_Module *obj, int session, struct sock
if (obj->consentFreshnessDisabled == 0) // TODO: Bryan: We should really put this after SCTP has been established...
{
// Start Consent Freshness Algorithm. Wait for the Timeout, then send first packet
obj->dTlsSessions[session]->freshnessTimestampStart = 0;
ILibLifeTime_Add(obj->Timer, ILibWebRTC_DTLS_TO_CONSENT_FRESHNESS_TIMER_OBJECT(obj->dTlsSessions[session]), ILibStun_MaxConsentFreshnessTimeoutSeconds, ILibStun_WebRTC_ConsentFreshness_Start, NULL);
}
}