[common/client] platform: add portable worker primitives

This commit is contained in:
Geoffrey McRae
2026-09-12 08:26:43 +10:00
parent 9c8343df96
commit 62a8786fe2
13 changed files with 417 additions and 108 deletions

View File

@@ -0,0 +1,29 @@
/**
* Looking Glass
* Copyright © 2017-2026 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_LG_COMMON_RANDOM_
#define _H_LG_COMMON_RANDOM_
#include <stdbool.h>
#include <stddef.h>
bool lgRandomBytes(void * buffer, size_t size);
#endif

View File

@@ -0,0 +1,33 @@
/**
* Looking Glass
* Copyright © 2017-2026 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_LG_COMMON_SEMAPHORE_
#define _H_LG_COMMON_SEMAPHORE_
#include <stdbool.h>
typedef struct LGSemaphore LGSemaphore;
LGSemaphore * lgCreateSemaphore(unsigned int initialValue);
void lgFreeSemaphore (LGSemaphore * semaphore);
bool lgWaitSemaphore (LGSemaphore * semaphore);
bool lgSignalSemaphore(LGSemaphore * semaphore);
#endif

View File

@@ -12,6 +12,8 @@ add_library(lg_common_platform_code STATIC
sysinfo.c
thread.c
event.c
semaphore.c
random.c
ivshmem.c
time.c
paths.c

View File

@@ -0,0 +1,43 @@
/**
* Looking Glass
* Copyright © 2017-2026 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "common/random.h"
#include <errno.h>
#include <stdint.h>
#include <sys/random.h>
bool lgRandomBytes(void * buffer, size_t size)
{
uint8_t * output = buffer;
while (size)
{
const ssize_t received = getrandom(output, size, 0);
if (received < 0 && errno == EINTR)
continue;
if (received <= 0)
return false;
output += (size_t)received;
size -= (size_t)received;
}
return true;
}

View File

@@ -0,0 +1,80 @@
/**
* Looking Glass
* Copyright © 2017-2026 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "common/semaphore.h"
#include "common/debug.h"
#include <errno.h>
#include <semaphore.h>
#include <stdlib.h>
#include <string.h>
struct LGSemaphore
{
sem_t handle;
};
LGSemaphore * lgCreateSemaphore(unsigned int initialValue)
{
LGSemaphore * semaphore = malloc(sizeof(*semaphore));
if (!semaphore)
return NULL;
if (sem_init(&semaphore->handle, 0, initialValue) != 0)
{
DEBUG_ERROR("Failed to create semaphore: %s", strerror(errno));
free(semaphore);
return NULL;
}
return semaphore;
}
void lgFreeSemaphore(LGSemaphore * semaphore)
{
if (!semaphore)
return;
if (sem_destroy(&semaphore->handle) != 0)
DEBUG_ERROR("Failed to destroy semaphore: %s", strerror(errno));
free(semaphore);
}
bool lgWaitSemaphore(LGSemaphore * semaphore)
{
int result;
do
result = sem_wait(&semaphore->handle);
while (result != 0 && errno == EINTR);
if (result != 0)
DEBUG_ERROR("Failed to wait on semaphore: %s", strerror(errno));
return result == 0;
}
bool lgSignalSemaphore(LGSemaphore * semaphore)
{
if (sem_post(&semaphore->handle) == 0)
return true;
DEBUG_ERROR("Failed to signal semaphore: %s", strerror(errno));
return false;
}

View File

@@ -35,6 +35,8 @@ add_library(lg_common_platform_code STATIC
sysinfo.c
thread.c
event.c
semaphore.c
random.c
windebug.c
ivshmem.c
time.c
@@ -46,6 +48,7 @@ add_library(lg_common_platform_code STATIC
target_link_libraries(lg_common_platform_code
lg_common
setupapi
bcrypt
ntdll
)

View File

@@ -0,0 +1,43 @@
/**
* Looking Glass
* Copyright © 2017-2026 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "common/random.h"
#include <limits.h>
#include <stdint.h>
#include <windows.h>
#include <bcrypt.h>
bool lgRandomBytes(void * buffer, size_t size)
{
uint8_t * output = buffer;
while (size)
{
const ULONG chunk = size > ULONG_MAX ? ULONG_MAX : (ULONG)size;
if (!BCRYPT_SUCCESS(BCryptGenRandom(
NULL, output, chunk, BCRYPT_USE_SYSTEM_PREFERRED_RNG)))
return false;
output += chunk;
size -= chunk;
}
return true;
}

View File

@@ -0,0 +1,83 @@
/**
* Looking Glass
* Copyright © 2017-2026 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "common/semaphore.h"
#include "common/debug.h"
#include "common/windebug.h"
#include <limits.h>
#include <stdlib.h>
#include <windows.h>
struct LGSemaphore
{
HANDLE handle;
};
LGSemaphore * lgCreateSemaphore(unsigned int initialValue)
{
if (initialValue > (unsigned int)LONG_MAX)
return NULL;
LGSemaphore * semaphore = malloc(sizeof(*semaphore));
if (!semaphore)
return NULL;
semaphore->handle = CreateSemaphoreW(
NULL, (LONG)initialValue, LONG_MAX, NULL);
if (!semaphore->handle)
{
DEBUG_WINERROR("Failed to create semaphore", GetLastError());
free(semaphore);
return NULL;
}
return semaphore;
}
void lgFreeSemaphore(LGSemaphore * semaphore)
{
if (!semaphore)
return;
if (!CloseHandle(semaphore->handle))
DEBUG_WINERROR("Failed to destroy semaphore", GetLastError());
free(semaphore);
}
bool lgWaitSemaphore(LGSemaphore * semaphore)
{
const DWORD result = WaitForSingleObject(semaphore->handle, INFINITE);
if (result == WAIT_OBJECT_0)
return true;
DEBUG_WINERROR("Failed to wait on semaphore", GetLastError());
return false;
}
bool lgSignalSemaphore(LGSemaphore * semaphore)
{
if (ReleaseSemaphore(semaphore->handle, 1, NULL))
return true;
DEBUG_WINERROR("Failed to signal semaphore", GetLastError());
return false;
}