diff --git a/source/tests/Makefile b/source/tests/Makefile index 4da679543..afbd99f13 100644 --- a/source/tests/Makefile +++ b/source/tests/Makefile @@ -11,6 +11,8 @@ CXXLANG ?= clang++ MODULEDIR=../../build/modules/Debug +WINECXX ?= wineg++ + # -------------------------------------------------------------- BASE_FLAGS = -Wall -Wextra -Werror -pipe -DBUILDING_CARLA -DREAL_BUILD -DDEBUG -O0 -g @@ -172,6 +174,10 @@ ifneq ($(WIN32),true) set -e; ./$@ && valgrind --leak-check=full ./$@ endif +WineJack: WineJack.cpp + $(WINECXX) $< $(BASE_FLAGS) -m32 -ljack -lpthread -o $@ + set -e; ./$@.exe + # -------------------------------------------------------------- sem: sem.cpp $(MODULEDIR)/jackbridge/* diff --git a/source/tests/WineJack.cpp b/source/tests/WineJack.cpp new file mode 100644 index 000000000..1160f8fea --- /dev/null +++ b/source/tests/WineJack.cpp @@ -0,0 +1,142 @@ +/* + * Wine+JACK Test + * Copyright (C) 2015 Filipe Coelho + * + * 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 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. + * + * For a full copy of the GNU General Public License see the doc/GPL.txt file. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#undef _WIN32 +#include + +static bool gCloseNow = false; + +static void _close(int) +{ + gCloseNow = true; +} + +static int _process(jack_nframes_t, void*) +{ + printf("%s\n", __PRETTY_FUNCTION__); + return 0; +} + +#if 0 +// TEST +void* (*creator_func)(void*) = NULL; +void* creator_arg = NULL; +HANDLE creator_handle = 0; +pthread_t creator_pthread = 0; + +static DWORD WINAPI thread_creator_helper(LPVOID) +{ + printf("%s\n", __PRETTY_FUNCTION__); + creator_pthread = pthread_self(); + SetEvent(creator_handle); + creator_func(creator_arg); + return 0; +} + +static int thread_creator(pthread_t* thread_id, const pthread_attr_t*, void *(*function)(void*), void* arg) +{ + printf("%s\n", __PRETTY_FUNCTION__); + creator_func = function; + creator_arg = arg; + creator_handle = ::CreateEventA(NULL, false, false, NULL); + + ::CreateThread(NULL, 0, thread_creator_helper, arg, 0, 0); + ::WaitForSingleObject(creator_handle, INFINITE); + + *thread_id = creator_pthread; + return 0; +} +#endif + +struct JackWineThread { + void* (*func)(void*); + void* arg; + pthread_t pthid; + sem_t sema; +}; + +static DWORD WINAPI +wine_thread_aux( LPVOID arg ) { + struct JackWineThread* jwt = (struct JackWineThread*) arg; + + printf("%s\n", __PRETTY_FUNCTION__); + + void* func_arg = jwt->arg; + void* (*func)(void*) = jwt->func; + + jwt->pthid = pthread_self(); + sem_post( &jwt->sema ); + + func ( func_arg ); + + return 0; +} + +static int +wine_thread_create (pthread_t* thread_id, const pthread_attr_t*, void *(*function)(void*), void* arg) { + struct JackWineThread jwt; + + printf("%s\n", __PRETTY_FUNCTION__); + + sem_init( &jwt.sema, 0, 0 ); + jwt.func = function; + jwt.arg = arg; + + CreateThread( NULL, 0, wine_thread_aux, &jwt, 0, 0 ); + sem_wait( &jwt.sema ); + + *thread_id = jwt.pthid; + return 0; +} + +int main() +{ + struct sigaction sterm; + sterm.sa_handler = _close; + sterm.sa_flags = SA_RESTART; + sterm.sa_restorer = NULL; + sigemptyset(&sterm.sa_mask); + sigaction(SIGTERM, &sterm, NULL); + sigaction(SIGINT, &sterm, NULL); + + jack_set_thread_creator(wine_thread_create); + + jack_client_t* const client = jack_client_open("WineJack2", JackNullOption, NULL); + if (client == NULL) + return 1; + + jack_set_process_callback(client, _process, NULL); + jack_activate(client); + + for (; ! gCloseNow;) { + usleep(100000); + } + + jack_deactivate(client); + jack_client_close(client); + + return 0; +}