...
 
......@@ -25,12 +25,15 @@ MEMBER steam_api_call_t ISteamMatchmaking_RequestLobbyList003(struct ISteamMatch
{
struct ISteamMatchmakingImpl *This = impl_from_ISteamMatchmaking(iface);
struct steam_callback_data_matchmaking_lobby_match_list lobby_match_list;
steam_api_call_t api_call;
LOG_ENTER_NOTIMPL("(This = %p)", VOIDPTR(This));
lobby_match_list.count = 0;
return callbacks_dispatch_api_call_result_output(STEAM_CALLBACK_TYPE_MATCHMAKING_LOBBY_MATCH_LIST, STEAM_FALSE, &lobby_match_list, sizeof(lobby_match_list));
api_call = callbacks_await_api_call_result_output();
callbacks_dispatch_api_call_result_output(api_call, STEAM_CALLBACK_TYPE_MATCHMAKING_LOBBY_MATCH_LIST, STEAM_FALSE, &lobby_match_list, sizeof(lobby_match_list));
return api_call;
}
MEMBER void ISteamMatchmaking_AddRequestLobbyListStringFilter(struct ISteamMatchmaking *iface, const char *key, const char *value, enum steam_matchmaking_lobby_comparison comparison)
......@@ -86,13 +89,16 @@ MEMBER steam_api_call_t ISteamMatchmaking_CreateLobby007(struct ISteamMatchmakin
{
struct ISteamMatchmakingImpl *This = impl_from_ISteamMatchmaking(iface);
struct steam_callback_data_matchmaking_lobby_created lobby_created;
steam_api_call_t api_call;
LOG_ENTER_NOTIMPL("(This = %p, type = %u, max_members = %d)", VOIDPTR(This), type, max_members);
lobby_created.result = STEAM_RESULT_FAIL;
lobby_created.steam_id_lobby.raw = 0;
return callbacks_dispatch_api_call_result_output(STEAM_CALLBACK_TYPE_MATCHMAKING_LOBBY_CREATED, STEAM_FALSE, &lobby_created, sizeof(lobby_created));
api_call = callbacks_await_api_call_result_output();
callbacks_dispatch_api_call_result_output(api_call, STEAM_CALLBACK_TYPE_MATCHMAKING_LOBBY_CREATED, STEAM_FALSE, &lobby_created, sizeof(lobby_created));
return api_call;
}
struct ISteamMatchmaking *SteamMatchmaking_generic(const char *version)
......
......@@ -28,6 +28,7 @@ MEMBER steam_api_call_t ISteamUGC_SendQueryUGCRequest(struct ISteamUGC *iface, s
{
struct ISteamUGCImpl *This = impl_from_ISteamUGC(iface);
struct steam_callback_data_ugc_query_completed ugc_query_completed;
steam_api_call_t api_call;
LOG_ENTER_NOTIMPL("(This = %p, handle = %" PRIu64 ")", VOIDPTR(This), handle);
......@@ -37,7 +38,9 @@ MEMBER steam_api_call_t ISteamUGC_SendQueryUGCRequest(struct ISteamUGC *iface, s
ugc_query_completed.total_count = 0;
ugc_query_completed.is_data_cached = STEAM_FALSE;
return callbacks_dispatch_api_call_result_output(STEAM_CALLBACK_TYPE_CLIENT_UGC_QUERY_COMPLETED, STEAM_FALSE, &ugc_query_completed, sizeof(ugc_query_completed));
api_call = callbacks_await_api_call_result_output();
callbacks_dispatch_api_call_result_output(api_call, STEAM_CALLBACK_TYPE_CLIENT_UGC_QUERY_COMPLETED, STEAM_FALSE, &ugc_query_completed, sizeof(ugc_query_completed));
return api_call;
}
MEMBER steam_bool_t ISteamUGC_ReleaseQueryUGCRequest(struct ISteamUGC *iface, steam_ugc_query_handle_t handle)
......
......@@ -167,12 +167,15 @@ MEMBER steam_api_call_t ISteamUser_RequestEncryptedAppTicket(struct ISteamUser *
{
struct ISteamUserImpl *This = impl_from_ISteamUser(iface);
struct steam_callback_data_user_encrypted_app_ticket_response encrypted_app_ticket_response;
steam_api_call_t api_call;
LOG_ENTER("(This = %p, data = %p, data_size = %d)", VOIDPTR(This), data, data_size);
encrypted_app_ticket_response.result = STEAM_RESULT_FAIL;
return callbacks_dispatch_api_call_result_output(STEAM_CALLBACK_TYPE_USER_ENCRYPTED_APP_TICKET_RESPONSE, STEAM_TRUE, &encrypted_app_ticket_response, sizeof(encrypted_app_ticket_response));
api_call = callbacks_await_api_call_result_output();
callbacks_dispatch_api_call_result_output(api_call, STEAM_CALLBACK_TYPE_USER_ENCRYPTED_APP_TICKET_RESPONSE, STEAM_TRUE, &encrypted_app_ticket_response, sizeof(encrypted_app_ticket_response));
return api_call;
}
struct ISteamUser *SteamUser_generic(const char *version)
......
......@@ -193,6 +193,7 @@ MEMBER steam_api_call_t ISteamUserStats_RequestUserStats(struct ISteamUserStats
{
struct ISteamUserStatsImpl *This = impl_from_ISteamUserStats(iface);
struct steam_callback_data_user_stats_user_stats_received user_stats_received;
steam_api_call_t api_call;
LOG_ENTER_NOTIMPL("(This = %p, steam_id_user = %#" PRIx64 ")", VOIDPTR(This), steam_id_user.raw);
......@@ -200,46 +201,57 @@ MEMBER steam_api_call_t ISteamUserStats_RequestUserStats(struct ISteamUserStats
user_stats_received.result = STEAM_RESULT_OK;
user_stats_received.steam_id_user = steam_id_user;
return callbacks_dispatch_api_call_result_output(STEAM_CALLBACK_TYPE_USER_STATS_USER_STATS_RECEIVED, STEAM_FALSE, &user_stats_received, sizeof(user_stats_received));
api_call = callbacks_await_api_call_result_output();
callbacks_dispatch_api_call_result_output(api_call, STEAM_CALLBACK_TYPE_USER_STATS_USER_STATS_RECEIVED, STEAM_FALSE, &user_stats_received, sizeof(user_stats_received));
return api_call;
}
MEMBER steam_api_call_t ISteamUserStats_FindOrCreateLeaderboard(struct ISteamUserStats *iface, const char *name, enum steam_user_stats_leaderboard_sort_method sort_method, enum steam_user_stats_leaderboard_display_type display_type)
{
struct ISteamUserStatsImpl *This = impl_from_ISteamUserStats(iface);
struct steam_callback_data_user_stats_leaderboard_find_result leaderboard_find_result;
steam_api_call_t api_call;
LOG_ENTER_NOTIMPL("(This = %p, name = \"%s\", sort_method = %u, display_type = %u)", VOIDPTR(This), debug_str(name), sort_method, display_type);
leaderboard_find_result.leaderboard = 0;
leaderboard_find_result.found = STEAM_FALSE;
return callbacks_dispatch_api_call_result_output(STEAM_CALLBACK_TYPE_USER_STATS_LEADERBOARD_FIND_RESULT, STEAM_FALSE, &leaderboard_find_result, sizeof(leaderboard_find_result));
api_call = callbacks_await_api_call_result_output();
callbacks_dispatch_api_call_result_output(api_call, STEAM_CALLBACK_TYPE_USER_STATS_LEADERBOARD_FIND_RESULT, STEAM_FALSE, &leaderboard_find_result, sizeof(leaderboard_find_result));
return api_call;
}
MEMBER steam_api_call_t ISteamUserStats_FindLeaderboard(struct ISteamUserStats *iface, const char *name)
{
struct ISteamUserStatsImpl *This = impl_from_ISteamUserStats(iface);
struct steam_callback_data_user_stats_leaderboard_find_result leaderboard_find_result;
steam_api_call_t api_call;
LOG_ENTER_NOTIMPL("(This = %p, name = \"%s\")", VOIDPTR(This), debug_str(name));
leaderboard_find_result.leaderboard = 0;
leaderboard_find_result.found = STEAM_FALSE;
return callbacks_dispatch_api_call_result_output(STEAM_CALLBACK_TYPE_USER_STATS_LEADERBOARD_FIND_RESULT, STEAM_FALSE, &leaderboard_find_result, sizeof(leaderboard_find_result));
api_call = callbacks_await_api_call_result_output();
callbacks_dispatch_api_call_result_output(api_call, STEAM_CALLBACK_TYPE_USER_STATS_LEADERBOARD_FIND_RESULT, STEAM_FALSE, &leaderboard_find_result, sizeof(leaderboard_find_result));
return api_call;
}
MEMBER steam_api_call_t ISteamUserStats_RequestGlobalStats(struct ISteamUserStats *iface, int history_days_count)
{
struct ISteamUserStatsImpl *This = impl_from_ISteamUserStats(iface);
struct steam_callback_data_user_stats_global_stats_received global_stats_received;
steam_api_call_t api_call;
LOG_ENTER_NOTIMPL("(This = %p, history_days_count = %d)", VOIDPTR(This), history_days_count);
global_stats_received.game_id = dsa_config_get_steam_game_id();
global_stats_received.result = STEAM_RESULT_OK;
return callbacks_dispatch_api_call_result_output(STEAM_CALLBACK_TYPE_USER_STATS_GLOBAL_STATS_RECEIVED, STEAM_FALSE, &global_stats_received, sizeof(global_stats_received));
api_call = callbacks_await_api_call_result_output();
callbacks_dispatch_api_call_result_output(api_call, STEAM_CALLBACK_TYPE_USER_STATS_GLOBAL_STATS_RECEIVED, STEAM_FALSE, &global_stats_received, sizeof(global_stats_received));
return api_call;
}
MEMBER steam_bool_t ISteamUserStats_GetGlobalStatI64(struct ISteamUserStats *iface, const char *name, int64_t *data)
......
......@@ -72,6 +72,7 @@ objs := \
config.c.o \
debug.c.o \
dsa.c.o \
jobserver.c.o \
setup_ifaces.c.o \
steam_api.c.o \
steam_gameserver.c.o \
......
......@@ -151,26 +151,29 @@ void callbacks_dispatch_callback_output(enum steam_callback_type type, void *dat
list_unlock(&call_outputs);
}
steam_api_call_t callbacks_dispatch_api_call_result_output(enum steam_callback_type type, steam_bool_t io_failure, void *data, size_t data_size)
steam_api_call_t callbacks_await_api_call_result_output(void)
{
return ++last_api_call_id;
}
void callbacks_dispatch_api_call_result_output(steam_api_call_t api_call, enum steam_callback_type type, steam_bool_t io_failure, void *data, size_t data_size)
{
struct call_output out;
if (type >= STEAM_CALLBACK_TYPE_MAX)
return 0;
return;
out.type = type;
out.is_api_call = STEAM_TRUE;
out.is_handled = STEAM_FALSE;
out.io_failure = io_failure;
out.api_call = ++last_api_call_id;
out.api_call = api_call;
out.data = dsa_utils_memdup(data, data_size);
out.data_size = data_size;
list_lock(&call_outputs);
list_push(&call_outputs, &out, sizeof(out));
list_unlock(&call_outputs);
return out.api_call;
}
static int remove_call_output_unsafe(struct list_elem *elem)
......
......@@ -11,7 +11,8 @@ void callbacks_unregister_callback(struct CCallbackBase *callback);
void callbacks_register_api_call_result(struct CCallbackBase *callback, steam_api_call_t api_call);
void callbacks_unregister_api_call_result(struct CCallbackBase *callback, steam_api_call_t api_call);
void callbacks_dispatch_callback_output(enum steam_callback_type type, void *data, size_t data_size);
steam_api_call_t callbacks_dispatch_api_call_result_output(enum steam_callback_type type, steam_bool_t io_failure, void *data, size_t data_size);
steam_api_call_t callbacks_await_api_call_result_output(void);
void callbacks_dispatch_api_call_result_output(steam_api_call_t api_call, enum steam_callback_type type, steam_bool_t io_failure, void *data, size_t data_size);
steam_bool_t callbacks_api_call_result_is_output_available(steam_api_call_t api_call, steam_bool_t *io_failure);
steam_bool_t callbacks_api_call_result_get_output(steam_api_call_t api_call, void *data, int data_size, enum steam_callback_type type_expected, steam_bool_t *io_failure);
void callbacks_run(void);
......
#include "config.h"
#include "callbacks.h"
#include "jobserver.h"
int dsa_init(void)
{
int result;
/* Here, none of the functions of os can be used,
except: dsa_os_thread*(), dsa_os_mutex*(), dsa_os_semaphore*(), dsa_os_mkdir() */
result = dsa_config_init();
if (result < 0)
return result;
result = dsa_jobserver_init();
if (result < 0)
return result;
result = callbacks_init();
if (result < 0)
return result;
......
#include "list.h"
#include "os/os.h"
#include "steam.h"
#include "jobserver.h"
#define THREAD_POOL_SIZE 4
struct dsa_jobserver_job
{
dsa_jobserver_callback_t callback;
char arg[];
};
struct dsa_jobserver_pool_thread_arg
{
struct dsa_jobserver_ctx *ctx;
struct dsa_os_thread *thrd;
};
struct dsa_jobserver_ctx
{
struct list jobs;
struct dsa_os_semaphore *job_sem;
struct dsa_jobserver_pool_thread_arg pool[THREAD_POOL_SIZE];
};
static struct dsa_jobserver_ctx jobserver_ctx;
static void dsa_jobserver_exit_callback(void *arg)
{
(void)arg;
}
static void dsa_jobserver_pool_thread_ep(void *arg)
{
struct dsa_jobserver_pool_thread_arg *targ = (struct dsa_jobserver_pool_thread_arg *)arg;
struct dsa_jobserver_ctx *ctx = targ->ctx;
steam_bool_t exit_thrd = STEAM_FALSE;
while (!exit_thrd)
{
struct list_elem *elem;
struct dsa_jobserver_job *job;
dsa_os_semaphore_wait(ctx->job_sem);
list_lock(&ctx->jobs);
elem = list_head(&ctx->jobs);
list_extract(&ctx->jobs, elem);
job = (struct dsa_jobserver_job *)list_get_data(elem);
list_unlock(&ctx->jobs);
if (job->callback == dsa_jobserver_exit_callback)
exit_thrd = STEAM_TRUE;
job->callback(job->arg);
free(elem);
}
}
int dsa_jobserver_init(void)
{
list_init(&jobserver_ctx.jobs);
jobserver_ctx.job_sem = dsa_os_semaphore_create(0);
for (size_t i = 0; i < THREAD_POOL_SIZE; i++)
{
struct dsa_jobserver_pool_thread_arg *targ = &jobserver_ctx.pool[i];
targ->ctx = &jobserver_ctx;
targ->thrd = dsa_os_thread_create(dsa_jobserver_pool_thread_ep, targ);
}
return 0;
}
int dsa_jobserver_deinit(void)
{
for (size_t i = 0; i < THREAD_POOL_SIZE; i++)
dsa_jobserver_schedule(dsa_jobserver_exit_callback, NULL, 0);
for (size_t i = 0; i < THREAD_POOL_SIZE; i++)
{
struct dsa_jobserver_pool_thread_arg *targ = &jobserver_ctx.pool[i];
dsa_os_thread_wait(targ->thrd);
dsa_os_thread_destroy(targ->thrd);
}
dsa_os_semaphore_destroy(jobserver_ctx.job_sem);
list_deinit(&jobserver_ctx.jobs);
return 0;
}
int dsa_jobserver_schedule(dsa_jobserver_callback_t callback, void *arg, size_t arg_size)
{
struct dsa_jobserver_job *job;
size_t job_size = sizeof(*job) + arg_size;
char data[job_size];
job = (struct dsa_jobserver_job *)data;
job->callback = callback;
if (arg && arg_size)
memcpy(job->arg, arg, arg_size);
list_lock(&jobserver_ctx.jobs);
list_push(&jobserver_ctx.jobs, job, job_size);
list_unlock(&jobserver_ctx.jobs);
dsa_os_semaphore_signal(jobserver_ctx.job_sem);
return 0;
}
#ifndef JOBSERVER_H
#define JOBSERVER_H 1
typedef void (*dsa_jobserver_callback_t)(void *arg);
extern int dsa_jobserver_init(void);
extern int dsa_jobserver_deinit(void);
extern int dsa_jobserver_schedule(dsa_jobserver_callback_t callback, void *arg, size_t arg_size);
#endif /* JOBSERVER_H */
......@@ -130,4 +130,11 @@ static inline int list_clear(struct list *l) {
return 0;
}
static inline int list_deinit(struct list *l) {
list_clear(l);
dsa_os_mutex_destroy(l->mtx);
return 0;
}
#endif /* LIST_H */
#define _GNU_SOURCE 1
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <sched.h>
#include <pthread.h>
#include <pwd.h>
#include <stdlib.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/stat.h> /* mkdir() */
#include <sys/types.h>
#include <unistd.h>
......@@ -17,11 +22,23 @@
#define CONSTRUCTOR __attribute__((constructor))
#define DESTRUCTOR __attribute__((destructor))
struct dsa_os_thread
{
dsa_os_thread_entry_point_t ep;
void *arg;
pthread_t thrd;
};
struct dsa_os_mutex
{
pthread_mutex_t mtx;
};
struct dsa_os_semaphore
{
sem_t sem;
};
static struct
{
char *home_dir;
......@@ -33,6 +50,8 @@ CONSTRUCTOR static void dsa_os_init(void)
{
const char steam_dir[] = "/.local/share/Steam";
dsa_init();
dl_override_init();
/* home_dir */
......@@ -61,8 +80,6 @@ CONSTRUCTOR static void dsa_os_init(void)
WARN0("Failed to define steam directory.");
os_ctx.steam_dir = dsa_utils_strdup("${STEAM_DIR}");
}
dsa_init();
}
DESTRUCTOR static void dsa_os_deinit(void)
......@@ -83,6 +100,76 @@ const char *dsa_os_get_steam_dir(void)
return os_ctx.steam_dir;
}
static void *dsa_os_thrd_wrapper(void *arg)
{
struct dsa_os_thread *thrd = (struct dsa_os_thread *)arg;
thrd->ep(thrd->arg);
return NULL;
}
struct dsa_os_thread *dsa_os_thread_create(dsa_os_thread_entry_point_t ep, void *arg)
{
struct dsa_os_thread *thrd;
int ret;
thrd = malloc(sizeof(*thrd));
if (!thrd)
return NULL;
thrd->ep = ep;
thrd->arg = arg;
ret = pthread_create(&thrd->thrd, NULL, dsa_os_thrd_wrapper, thrd);
if (ret != 0)
{
free(thrd);
return NULL;
}
return thrd;
}
void dsa_os_thread_destroy(struct dsa_os_thread *thrd)
{
free(thrd);
}
int dsa_os_thread_kill(struct dsa_os_thread *thrd)
{
int ret;
ret = pthread_kill(thrd->thrd, SIGKILL);
if (ret != 0)
return -1;
return 0;
}
int dsa_os_thread_wait(struct dsa_os_thread *thrd)
{
int ret;
ret = pthread_join(thrd->thrd, NULL);
if (ret != 0)
return -1;
return 0;
}
int dsa_os_thread_trywait(struct dsa_os_thread *thrd)
{
int ret;
ret = pthread_tryjoin_np(thrd->thrd, NULL);
if (ret != 0)
return -1;
return 0;
}
void dsa_os_thread_yield(void)
{
sched_yield();
}
struct dsa_os_mutex *dsa_os_mutex_create(void)
{
struct dsa_os_mutex *mtx;
......@@ -144,6 +231,61 @@ int dsa_os_mutex_unlock(struct dsa_os_mutex *mtx)
return 0;
}
struct dsa_os_semaphore *dsa_os_semaphore_create(unsigned int val)
{
struct dsa_os_semaphore *sem;
int ret;
sem = malloc(sizeof(*sem));
if (!sem)
return NULL;
ret = sem_init(&sem->sem, 0, val);
if (ret < 0)
{
free(sem);
return NULL;
}
return sem;
}
void dsa_os_semaphore_destroy(struct dsa_os_semaphore *sem)
{
sem_destroy(&sem->sem);
free(sem);
}
int dsa_os_semaphore_signal(struct dsa_os_semaphore *sem)
{
int ret;
ret = sem_post(&sem->sem);
if (ret < 0)
return -1;
return 0;
}
int dsa_os_semaphore_wait(struct dsa_os_semaphore *sem)
{
int ret;
ret = sem_wait(&sem->sem);
if (ret < 0)
return -1;
return 0;
}
int dsa_os_semaphore_trywait(struct dsa_os_semaphore *sem)
{
int ret;
ret = sem_trywait(&sem->sem);
if (ret < 0)
return -1;
return 0;
}
int dsa_os_mkdir(const char *path)
{
return mkdir(path, 0777);
......
#ifndef OS_OS_H
#define OS_OS_H 1
struct dsa_os_thread;
struct dsa_os_mutex;
struct dsa_os_semaphore;
typedef void (*dsa_os_thread_entry_point_t)(void *arg);
extern const char *dsa_os_get_home_dir(void);
extern const char *dsa_os_get_steam_dir(void);
extern struct dsa_os_thread *dsa_os_thread_create(dsa_os_thread_entry_point_t ep, void *arg);
extern void dsa_os_thread_destroy(struct dsa_os_thread *thrd);
extern int dsa_os_thread_kill(struct dsa_os_thread *thrd);
extern int dsa_os_thread_wait(struct dsa_os_thread *thrd);
extern int dsa_os_thread_trywait(struct dsa_os_thread *thrd);
extern void dsa_os_thread_yield(void);
extern struct dsa_os_mutex *dsa_os_mutex_create(void);
extern void dsa_os_mutex_destroy(struct dsa_os_mutex *mtx);
extern int dsa_os_mutex_lock(struct dsa_os_mutex *mtx);
extern int dsa_os_mutex_trylock(struct dsa_os_mutex *mtx);
extern int dsa_os_mutex_unlock(struct dsa_os_mutex *mtx);
extern struct dsa_os_semaphore *dsa_os_semaphore_create(unsigned int val);
extern void dsa_os_semaphore_destroy(struct dsa_os_semaphore *sem);
extern int dsa_os_semaphore_signal(struct dsa_os_semaphore *sem);
extern int dsa_os_semaphore_wait(struct dsa_os_semaphore *sem);
extern int dsa_os_semaphore_trywait(struct dsa_os_semaphore *sem);
extern int dsa_os_mkdir(const char *path);
#endif /* OS_OS_H */
#include <limits.h>
#include <string.h>
#include <userenv.h>
#include <windows.h>
......@@ -10,11 +13,23 @@
# define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3)
#endif
struct dsa_os_thread
{
dsa_os_thread_entry_point_t ep;
void *arg;
HANDLE handle;
};
struct dsa_os_mutex
{
CRITICAL_SECTION cs;
};
struct dsa_os_semaphore
{
HANDLE handle;
};
static struct
{
char *home_dir;
......@@ -29,6 +44,8 @@ static int dsa_os_init(void)
DWORD size;
HKEY steam_key;
dsa_init();
os_ctx.home_dir = NULL;
os_ctx.steam_dir = NULL;
......@@ -74,8 +91,6 @@ static int dsa_os_init(void)
os_ctx.steam_dir = dsa_utils_strdup("${STEAM_DIR}");
}
dsa_init();
return 0;
}
......@@ -99,6 +114,75 @@ const char *dsa_os_get_steam_dir(void)
return os_ctx.steam_dir;
}
static DWORD WINAPI dsa_os_thrd_wrapper(void *arg)
{
struct dsa_os_thread *thrd = (struct dsa_os_thread *)arg;
thrd->ep(thrd->arg);
return 0;
}
struct dsa_os_thread *dsa_os_thread_create(dsa_os_thread_entry_point_t ep, void *arg)
{
struct dsa_os_thread *thrd;
thrd = malloc(sizeof(*thrd));
if (!thrd)
return NULL;
thrd->ep = ep;
thrd->arg = arg;
thrd->handle = CreateThread(NULL, 0, dsa_os_thrd_wrapper, thrd, 0, NULL);
if (!thrd->handle)
{
free(thrd);
return NULL;
}
return thrd;
}
void dsa_os_thread_destroy(struct dsa_os_thread *thrd)
{
free(thrd);
}
int dsa_os_thread_kill(struct dsa_os_thread *thrd)
{
BOOL bret;
bret = TerminateThread(thrd->handle, 0);
if (!bret)
return -1;
return 0;
}
int dsa_os_thread_wait(struct dsa_os_thread *thrd)
{
DWORD dwret;
dwret = WaitForSingleObject(thrd->handle, INFINITE);
if (dwret != WAIT_OBJECT_0)
return -1;
return 0;
}
int dsa_os_thread_trywait(struct dsa_os_thread *thrd)
{
DWORD dwret;
dwret = WaitForSingleObject(thrd->handle, 0);
if (dwret != WAIT_OBJECT_0)
return -1;
return 0;
}
void dsa_os_thread_yield(void)
{
SwitchToThread();
}
struct dsa_os_mutex *dsa_os_mutex_create(void)
{
struct dsa_os_mutex *mtx;
......@@ -138,6 +222,60 @@ int dsa_os_mutex_unlock(struct dsa_os_mutex *mtx)
return 0;
}
struct dsa_os_semaphore *dsa_os_semaphore_create(unsigned int val)
{
struct dsa_os_semaphore *sem;
sem = malloc(sizeof(*sem));
if (!sem)
return NULL;
sem->handle = CreateSemaphoreA(NULL, val, LONG_MAX, NULL);
if (!sem->handle)
{
free(sem);
return NULL;
}
return sem;
}
void dsa_os_semaphore_destroy(struct dsa_os_semaphore *sem)
{
CloseHandle(sem->handle);
free(sem);
}
int dsa_os_semaphore_signal(struct dsa_os_semaphore *sem)
{
BOOL bret;
bret = ReleaseSemaphore(sem->handle, 1, NULL);
if (!bret)
return -1;
return 0;
}
int dsa_os_semaphore_wait(struct dsa_os_semaphore *sem)
{
DWORD dwret;
dwret = WaitForSingleObject(sem->handle, INFINITE);
if (dwret != WAIT_OBJECT_0)
return -1;
return 0;
}
int dsa_os_semaphore_trywait(struct dsa_os_semaphore *sem)
{
DWORD dwret;
dwret = WaitForSingleObject(sem->handle, 0);
if (dwret != WAIT_OBJECT_0)
return -1;
return 0;
}
int dsa_os_mkdir(const char *path)
{
BOOL ret;
......
#include <ctype.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
......@@ -171,3 +172,12 @@ char *dsa_utils_strdup(const char *s)
return dsa_utils_memdup(s, strlen(s) + 1);
}
int dsa_utils_strncasecmp(const char *s1, const char *s2)
{
int d;
while ((d = tolower(*s1++) - tolower(*s2++)) == 0 && s1[-1]);
return d;
}
......@@ -19,5 +19,6 @@ int dsa_utils_file_write(const char *filename, void *data, size_t size);
void dsa_utils_free_ptr(void *ptr);
void *dsa_utils_memdup(const void *data, size_t size);
char *dsa_utils_strdup(const char *str);
int dsa_utils_strncasecmp(const char *s1, const char *s2);
#endif /* UTILS_H */