wine 1.7.39 added

This commit is contained in:
Kolan Sh 2015-03-22 13:48:01 +03:00
parent 10e9e64f8b
commit 15e2186648
5 changed files with 189 additions and 679 deletions

View File

@ -1,6 +1,7 @@
DIST wine-1.7.37.tar.bz2 22034021 SHA256 6730ec79bc8d5f61ab90d9cb51daab26a57c1a79e2804e03731f060dea4af305 SHA512 235cdac2c037eaf95ec78634769534dcd10c844bbcd8b8b2f66d457a80779277d4c608d930a10e381a35d33bd30044de7242cd8ce148ecae62085e097e1bccc7 WHIRLPOOL 324dc54ec3a8d1fa661a617708a27435d6f366252deab483238f95f91be351dcfead31f7a3cfa118d66781565dc1a856bf9e10dfef99b915b4845dcd662a7d6d
DIST wine-gentoo-2013.06.24.tar.bz2 85442 SHA256 bfbf6b25e98f717320de2ede467e3628fbc749d936b8449f8477c9dc6f41e04b SHA512 b6819889314f6a6ea16c1332f4b177c43623116763969c31b23b61754cd304dd085f5d3eafbe847159331eb97dddd9b4c10699430129ea4a71da418c1fe175f0 WHIRLPOOL 227e0ac6569736d4ad5813cef49f775dae956f4fc9255de95753d5d3cba1bf6cf3db31d23d3702bb54d2e60c5a6f779b602f0efb2096e4c827c924565b273d00
DIST wine-mono-4.5.4.msi 28792947 SHA256 a3a9da5765c20af9077291f177de674e9656cc1b354dcab3ac8e34231640cfeb SHA512 337de3d91adc29e59f026b2a774bae9d975886e1a96ad7ced1dad1ae5d869b96f02a2fb3017f6ad8bec803c875d34a22285e38b867310907d4006622a5d29098 WHIRLPOOL ac35f94ef0a2b991623a225949a10587b39df599626b02ce81f7bbdf8799e45236ffc0489b3a7607c9f0d1f166b774a6571b379ea6b4b9448f9e219b4f8be675
DIST wine-staging-1.7.34.tar.gz 8865976 SHA256 9e71b5d3ce0cd8c4c511c375bcdae74de33d96dbda1d1e70fc7eb8708ee018dc SHA512 8c6b269eec6890ac0e724553c7a537c91b2420dc7d2ee96ba6fba911ad959d6b17e71a4e690539f3024450f4a7801be516977b1d1351e5f22820fdd44c78b7b1 WHIRLPOOL 93d32676f7150184ecfd676310c666299c4fc5ee0b0c04d2020ab06f330c982f54fde38c0d8986e51a9515a349d36b4fbf9cb31fefb378671eee8f112eb69fd3
DIST wine_gecko-2.34-x86.msi 28269568 SHA256 956c26bf302b1864f4d7cb6caee4fc83d4c1281157731761af6395b876e29ca7 SHA512 abc5a4ef496ee407579cd2f284cbcb03306a08cbf3cc4952f3339286aefb36737d2d641d8e72b10a02a4d71478964e676812452c12ff7cb6aaeaf5210408c358 WHIRLPOOL ef72209b4c63fc81f787644046c5fd168b8a5a4e7e5c8652eb7a78ce3b433d888512bdd5aab6ea07248c9c148175006666cd7a800bcfb2b3a73de3f50d1fab76
DIST wine_gecko-2.34-x86_64.msi 29802496 SHA256 0f2c1b24c4cd1b3fa3fb3fe31dcd9ee162446b1f3370c0a18c8cb03a0c1a1070 SHA512 6bc69e1c8612533b3f37c16782833bca0e3aaa8ae872fe9f347ee081575c55c03866d6c71a5fb767bf4c3b012ae72f7d9c384d6d25c2584bf349126521e8f463 WHIRLPOOL a03df2c16088cf573c9273a59ba6998455917a49e0bf84028136d0ecff65a91f20edbecec55455b742682dcee5f5e618b8f2e8c15c71625642cd8b67a7774bd0
DIST wine-1.7.34-gstreamer-v5.patch.bz2 5703 SHA256 c3bb6f669f46d9f2d7ba494a2264cee457349f559d4b0758db80e39eb22f2aee SHA512 e780394e8739a58593d264322c462bfe9040c1cabce93b84d24f09040026368efb4ac34a6a302beb6048d14b4ac835b87a0c515b52c1a0c143aa4e15691eb01b WHIRLPOOL 1befbb0fbd026d6e833c5d72341064dd6e12157e1b7df58e349b9985648bfbc63f70e9cab45b61155515ac65057968e30ba313e71e183b8027153c9392d89192
DIST wine-1.7.39.tar.bz2 22122289 SHA256 6affb007fe772eb5588c584e3bdb62db96d8291c7fc8e75a5fd0bb098391335c SHA512 0eda88c4c092c2d596097548a341f62128dc39ffd6c88c514378639864dfbeedad3cb436065a85981cb2d9399a4cf439d1c301ec651a7e21eac886931218b6f5 WHIRLPOOL 9cb9d99d94e5abecbf5c6717165b58c7c23784aef0a4ffe2edaca2aef63e5706f17aa1102e00424fd849b30598f5d3b8206ea6b473c4337bb486211d7c3daf46
DIST wine-gentoo-2015.03.07.tar.bz2 85419 SHA256 f13f93dc49bbc33a294c4d511b6e01aec2d38bff77a1e44d07668291add1ab04 SHA512 bae1d2d5575d340d01f44008104f0e5ec0c4a4982995dec37d501594cd21d07a2b4ad4465c4273646d5bf6521996b4b82471097864be75342abe3e7d478a56bd WHIRLPOOL 0f254dd692e87a1f71dd19f6c1c8c59b8a91b994e75912a2e6e3ba5e875b85119fe497a331a95c2ce33bbf5f064143d23ee00275da92c494227de0807c9abb06
DIST wine-mono-4.5.6.msi 53705216 SHA256 ac681f737f83742d786706529eb85f4bc8d6bdddd8dcdfa9e2e336b71973bc25 SHA512 4d8df04c1d0da09d1abe423dd271e5dd14a193d607fb54e214d2e340827f7c33829342d1580b6907d7cf466e70993d743c6e1ca9a026d4b6225dd7c1fc8b1386 WHIRLPOOL 9a68e502da0be6768e92d88f2ccace607300f3a331e0f9e1b6d60e9c6c2d4eb635b902f03e13aad73461dd5f0c2691c7b41958356ebb7f445e8def4282c675d3
DIST wine-staging-1.7.39.tar.gz 9096658 SHA256 b7b3ba39e2a8829a6fd6aef4b3701dd0009eebc85539ac946e31de6d7fe36649 SHA512 d14780c30303a17f575f22adeab5cc026c2f41520d47dbb7ec70b939252eae656070eb8532cf1a42cca2b1c9c589a44081d12b2647b0d97c3c90b896a7433d23 WHIRLPOOL 8d71a49c3172261e83193ccfe85dfbd94421ee20063f4127ecb328450916cddbea742c59c09c34e10035d9f2fa0df0ebd0d68bbc6e90b92c1aa1a1071a26b055
DIST wine_gecko-2.36-x86.msi 29718016 SHA256 afa457ce8f9885225b6e549dd6f154713ce15bf063c23e38c1327d2f869e128a SHA512 6099240fb76368ed9bb6b775d5972b6124972ace92ccfe1051caeb8884d9e12d40c35220419f0d02443584bf2d82799dfca8206410d171470ce15903703924f0 WHIRLPOOL 4b8fc20a8b228268f3407ca425427a2d91f81ff9e6f0860d4f3eb156c97e3ec1ea83ca3510ee10bfb37598f91c3323a46ba75eace3334632b26cbd45959dc908
DIST wine_gecko-2.36-x86_64.msi 31222784 SHA256 701b84004bf584a2dae7c1296121172c933321cb795c3817b64435fd3364ed44 SHA512 814b13268beeac4d0ace4ab62dbc29ccd92fc13a135499b8ea5a14355992d576268e1e401b28906e8379a826159c5bb051ad274a1e64dd0d5424d495f8e10e10 WHIRLPOOL dbd0e275bdca2ff7a1930daa62d23fd438a90f71b0fed1096b34b8d00a3f51cb91468ce61acaa9361a57deb9f3cfe70a21d16fc23de95cb4e0f7f957d4727010

View File

@ -1,629 +0,0 @@
From 9e081cd4a04e3326d4927aa082695f15432590e2 Mon Sep 17 00:00:00 2001
From: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date: Thu, 14 Aug 2014 11:49:20 +0200
Subject: [PATCH] TESTING -- override pthreads to fix gstreamer v4
I believe the code is ready and will work properly now in all cases.
but please test before cherry picking this patch, and report
success or failure to me please.
Changes since v1:
- Call pthread_yield to make sure that we link against libpthread.
This fixes the build on saucy.
Changes since v2:
- Set thread_data->detached before creating the thread to prevent
a race condition.
Changes since v3:
- Set thread_data->detached CORRECTLY. Fix a small race between
thread creation and pthread_detach.
---
dlls/ntdll/ntdll_misc.h | 3 +
dlls/ntdll/thread.c | 307 +++++++++++++++++++++++++++++++++++++--
dlls/winegstreamer/glibthread.c | 13 ++
libs/wine/loader.c | 7 +
libs/wine/wine.map | 6 +
loader/Makefile.in | 2 +-
loader/main.c | 41 +++++
7 files changed, 362 insertions(+), 17 deletions(-)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 4370084..1af819b 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -28,6 +28,7 @@
#include "winnt.h"
#include "winternl.h"
#include "wine/server.h"
+#include "wine/list.h"
#define MAX_NT_PATH_LENGTH 277
@@ -235,6 +236,8 @@ struct ntdll_thread_data
WINE_VM86_TEB_INFO vm86; /* 1fc vm86 private data */
void *exit_frame; /* 204 exit frame pointer */
#endif
+ struct list entry;
+ BOOL detached;
};
static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index c8461b0..8d5470e 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -33,6 +33,7 @@
#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif
+#include <errno.h>
#define NONAMELESSUNION
#include "ntstatus.h"
@@ -58,6 +59,7 @@ struct startup_info
TEB *teb;
PRTL_THREAD_START_ROUTINE entry_point;
void *entry_arg;
+ BOOL native_thread;
};
static PEB *peb;
@@ -202,6 +204,78 @@ static ULONG get_dyld_image_info_addr(void)
}
#endif /* __APPLE__ */
+#ifdef __linux__
+extern typeof(pthread_create) *__glob_pthread_create, *call_pthread_create;
+extern typeof(pthread_join) *__glob_pthread_join, *call_pthread_join;
+extern typeof(pthread_detach) *__glob_pthread_detach, *call_pthread_detach;
+
+static typeof(pthread_create) __hook_pthread_create;
+static typeof(pthread_join) __hook_pthread_join;
+static typeof(pthread_detach) __hook_pthread_detach;
+
+static pthread_mutex_t thread_lock;
+
+static void thread_wrap_init(void)
+{
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
+ pthread_mutex_init(&thread_lock, &attr);
+ pthread_mutexattr_destroy(&attr);
+
+ call_pthread_create = __hook_pthread_create;
+ call_pthread_join = __hook_pthread_join;
+ call_pthread_detach = __hook_pthread_detach;
+}
+
+static TEB *dead_teb;
+static struct list active_list = LIST_INIT(active_list);
+
+static void take_thread_lock(void)
+{
+ int ret = pthread_mutex_lock(&thread_lock);
+ if (ret == EOWNERDEAD)
+ pthread_mutex_consistent(&thread_lock);
+}
+
+static void detach_thread_unlock(TEB *own_teb)
+{
+ struct ntdll_thread_data *thread_data;
+ TEB *teb = dead_teb;
+
+ dead_teb = own_teb;
+
+ pthread_mutex_unlock(&thread_lock);
+ if (!teb)
+ return;
+
+ thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
+ __glob_pthread_join(thread_data->pthread_id, NULL);
+ signal_free_thread(teb);
+}
+
+static void reap_thread(TEB *teb)
+{
+ struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
+ take_thread_lock();
+ if (thread_data->detached)
+ detach_thread_unlock(teb);
+ else {
+ /*
+ * Do not unlock, wait until the thread is thoroughly dead.
+ * This prevents a race condition where detach is called
+ * after the thread has not finished dying yet.
+ */
+ }
+}
+
+#else
+#define __glob_pthread_create pthread_create
+#define __glob_pthread_join pthread_join
+#define __glob_pthread_detach pthread_detach
+#define thread_wrap_init()
+#endif
+
/***********************************************************************
* thread_init
*
@@ -220,6 +294,7 @@ HANDLE thread_init(void)
struct ntdll_thread_data *thread_data;
static struct debug_info debug_info; /* debug info for initial thread */
+ thread_wrap_init();
virtual_init();
/* reserve space for shared user data */
@@ -349,14 +424,12 @@ void terminate_thread( int status )
pthread_exit( UIntToPtr(status) );
}
-
-/***********************************************************************
- * exit_thread
- */
-void exit_thread( int status )
+static void exit_thread_common( int status )
{
+#ifndef __linux__
static void *prev_teb;
TEB *teb;
+#endif
if (status) /* send the exit code to the server (0 is already the default) */
{
@@ -380,24 +453,177 @@ void exit_thread( int status )
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
+#ifndef __linux__
if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() )))
{
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
if (thread_data->pthread_id)
{
- pthread_join( thread_data->pthread_id, NULL );
+ __glob_pthread_join( thread_data->pthread_id, NULL );
signal_free_thread( teb );
}
}
+#else
+ reap_thread(NtCurrentTeb());
+#endif
close( ntdll_get_thread_data()->wait_fd[0] );
close( ntdll_get_thread_data()->wait_fd[1] );
close( ntdll_get_thread_data()->reply_fd );
close( ntdll_get_thread_data()->request_fd );
+}
+
+void exit_thread( int status )
+{
+ exit_thread_common(status);
pthread_exit( UIntToPtr(status) );
}
+#ifdef __linux__
+
+struct unix_arg {
+ void *(*start)(void *);
+ void *arg;
+};
+
+/* dummy used for comparison */
+static DWORD native_unix_start;
+
+static void call_native_cleanup(void *arg)
+{
+ exit_thread_common(0);
+}
+
+static int
+__hook_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine) (void *), void *parm)
+{
+ NTSTATUS ret;
+ pthread_t tid;
+ size_t stack = 8 * 1024 * 1024;
+ struct unix_arg arg;
+ arg.start = start_routine;
+ arg.arg = parm;
+
+ if (!thread)
+ thread = &tid;
+
+ TRACE("Overriding thread creation!\n");
+ if (attr) {
+ static int once;
+ if (!once++)
+ FIXME("most thread attributes ignored!\n");
+ else
+ WARN("most thread attributes ignored!\n");
+
+ pthread_attr_getstacksize(attr, &stack);
+ }
+
+ ret = RtlCreateUserThread( NtCurrentProcess(), NULL, FALSE, NULL, stack, 0, (void*)&native_unix_start, &arg, NULL, (void*)thread );
+ if (ret != STATUS_SUCCESS)
+ FIXME("ret: %08x\n", ret);
+ switch (ret) {
+ case STATUS_SUCCESS:
+ TRACE("created thread %lx for %p/%p\n", *thread, start_routine, parm);
+ return 0;
+ case STATUS_NO_MEMORY:
+ return ENOMEM;
+ case STATUS_TOO_MANY_OPENED_FILES:
+ return EMFILE;
+ default:
+ ERR("Unhandled ntstatus %08x\n", ret);
+ return ENOMEM;
+ }
+}
+
+static int __hook_pthread_detach(pthread_t thread)
+{
+ struct ntdll_thread_data *thread_data;
+ TEB *teb = NULL;
+
+ if (pthread_equal(thread, pthread_self())) {
+ TRACE("Detached self: %lx\n", pthread_self());
+ ntdll_get_thread_data()->detached = 1;
+ return 0;
+ }
+
+ take_thread_lock();
+ LIST_FOR_EACH_ENTRY(thread_data, &active_list, typeof(*thread_data), entry) {
+ if (pthread_equal(thread_data->pthread_id, thread)) {
+ teb = CONTAINING_RECORD(thread_data, typeof(*teb), SpareBytes1);
+
+ list_remove(&thread_data->entry);
+ if (!pthread_tryjoin_np(thread, NULL)) {
+ detach_thread_unlock(NULL);
+ TRACE("Thread %lx was dead, cleaning up\n", thread);
+ signal_free_thread(teb);
+ return 0;
+ }
+ thread_data->detached = 1;
+ break;
+ }
+ }
+ detach_thread_unlock(NULL);
+ if (!teb)
+ TRACE("Could not find thread %lx to detach\n", thread);
+ else
+ TRACE("Changed thread %lx to detached\n", thread);
+ return teb ? 0 : ESRCH;
+}
+
+static int __hook_pthread_join(pthread_t thread, void **retval)
+{
+ struct ntdll_thread_data *thread_data, *t2;
+ int ret = ESRCH;
+
+ if (pthread_equal(thread, pthread_self()))
+ return EDEADLK;
+
+ take_thread_lock();
+ LIST_FOR_EACH_ENTRY(thread_data, &active_list, typeof(*thread_data), entry) {
+ TEB *teb = CONTAINING_RECORD(thread_data, typeof(*teb), SpareBytes1);
+
+ if (pthread_equal(thread, thread_data->pthread_id)) {
+
+ ret = pthread_tryjoin_np(thread, retval);
+ if (!ret) {
+ TRACE("Thread %lx was dead fastpath, cleaning up\n", thread);
+ goto free;
+ }
+ detach_thread_unlock(NULL);
+
+ ret = __glob_pthread_join(thread, retval);
+ if (ret) {
+ TRACE("Thread %lx join failed with %i, ignoring\n", thread, ret);
+ return ret;
+ }
+
+ take_thread_lock();
+ /* Check if someone else freed the thread yet */
+ LIST_FOR_EACH_ENTRY(t2, &active_list, typeof(*thread_data), entry)
+ if (t2 == thread_data) {
+ TRACE("Cleaning up after successful join\n");
+ goto free;
+ }
+ TRACE("No clean up after successful join, multiple pthread_join's?\n");
+ break;
+
+free:
+ list_remove(&thread_data->entry);
+ detach_thread_unlock(NULL);
+ signal_free_thread(teb);
+ return 0;
+ }
+ }
+
+ detach_thread_unlock(NULL);
+ if (ret)
+ TRACE("failed with %i\n", ret);
+ return ret;
+}
+
+#endif
/***********************************************************************
* start_thread
@@ -426,9 +652,19 @@ static void start_thread( struct startup_info *info )
if (TRACE_ON(relay))
DPRINTF( "%04x:Starting thread proc %p (arg=%p)\n", GetCurrentThreadId(), func, arg );
- call_thread_entry_point( (LPTHREAD_START_ROUTINE)func, arg );
-}
+#ifdef __linux__
+ if (info->native_thread) {
+ void *(*start)(void*) = (void*)func;
+ FIXME("Started native thread %08x\n", GetCurrentThreadId());
+ pthread_cleanup_push(call_native_cleanup, NULL);
+ pthread_exit(start(arg));
+ pthread_cleanup_pop(1);
+ return;
+ }
+#endif
+ call_thread_entry_point( (LPTHREAD_START_ROUTINE)func, arg );
+}
/***********************************************************************
* RtlCreateUserThread (NTDLL.@)
@@ -440,14 +676,13 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
HANDLE *handle_ptr, CLIENT_ID *id )
{
sigset_t sigset;
- pthread_t pthread_id;
pthread_attr_t attr;
struct ntdll_thread_data *thread_data;
struct startup_info *info = NULL;
HANDLE handle = 0, actctx = 0;
TEB *teb = NULL;
DWORD tid = 0;
- int request_pipe[2];
+ int request_pipe[2], ret;
NTSTATUS status;
if (process != NtCurrentProcess())
@@ -472,10 +707,14 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
if (handle_ptr) *handle_ptr = wine_server_ptr_handle( result.create_thread.handle );
else NtClose( wine_server_ptr_handle( result.create_thread.handle ));
}
+ TRACE("CreateThread for other process returns %08x\n", result.create_thread.status);
return result.create_thread.status;
}
- if (server_pipe( request_pipe ) == -1) return STATUS_TOO_MANY_OPENED_FILES;
+ if (server_pipe( request_pipe ) == -1) {
+ TRACE("CreateThread cannot create request pipe: %m\n");
+ return STATUS_TOO_MANY_OPENED_FILES;
+ }
wine_server_send_fd( request_pipe[0] );
SERVER_START_REQ( new_thread )
@@ -496,12 +735,16 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
if (status)
{
close( request_pipe[1] );
+ TRACE("CreateThread server request failed with %08x\n", status);
return status;
}
pthread_sigmask( SIG_BLOCK, &server_block_set, &sigset );
- if ((status = signal_alloc_thread( &teb ))) goto error;
+ if ((status = signal_alloc_thread( &teb ))) {
+ TRACE("CreateThread signal thread allocation failed with %08x\n", status);
+ goto error;
+ }
teb->Peb = NtCurrentTeb()->Peb;
teb->ClientId.UniqueProcess = ULongToHandle(GetCurrentProcessId());
@@ -524,32 +767,64 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
info = (struct startup_info *)(teb + 1);
info->teb = teb;
- info->entry_point = start;
- info->entry_arg = param;
+#ifdef __linux__
+ info->native_thread = (void*)start == (void*)&native_unix_start;
+ if (info->native_thread) {
+ struct unix_arg *arg = param;
+ info->entry_point = (void*)arg->start;
+ info->entry_arg = arg->arg;
+ } else
+#endif
+ {
+ info->entry_point = start;
+ info->entry_arg = param;
+ }
thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
+#ifdef __linux__
+ thread_data->detached = !info->native_thread;
+#endif
thread_data->request_fd = request_pipe[1];
thread_data->reply_fd = -1;
thread_data->wait_fd[0] = -1;
thread_data->wait_fd[1] = -1;
+ thread_data->entry.next = NULL;
- if ((status = virtual_alloc_thread_stack( teb, stack_reserve, stack_commit ))) goto error;
+ if ((status = virtual_alloc_thread_stack( teb, stack_reserve ?: (8 << 20), stack_commit ?: (1 << 20) ))) {
+ TRACE("Allocating virtual stack for %p (%li/%li) failed with %08x\n", start, stack_reserve, stack_commit, status);
+ goto error;
+ }
pthread_attr_init( &attr );
pthread_attr_setstack( &attr, teb->DeallocationStack,
(char *)teb->Tib.StackBase - (char *)teb->DeallocationStack );
pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); /* force creating a kernel thread */
interlocked_xchg_add( &nb_threads, 1 );
- if (pthread_create( &pthread_id, &attr, (void * (*)(void *))start_thread, info ))
+
+ take_thread_lock();
+ ret = __glob_pthread_create( &thread_data->pthread_id, &attr, (void * (*)(void *))start_thread, info );
+ if (ret)
{
+ TRACE("pthread create failed with %i/%m\n", ret);
interlocked_xchg_add( &nb_threads, -1 );
pthread_attr_destroy( &attr );
status = STATUS_NO_MEMORY;
goto error;
}
+ if (!thread_data->detached)
+ list_add_tail(&active_list, &thread_data->entry);
+ detach_thread_unlock(NULL);
+
pthread_attr_destroy( &attr );
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
+ TRACE("Created thread succesfully, win handle: %04x, pthread: %lx\n", tid, thread_data->pthread_id);
+
+#ifdef __linux__
+ if ((void*)start == (void*)&native_unix_start && id)
+ *(pthread_t*)id = thread_data->pthread_id;
+ else
+#endif
if (id) id->UniqueThread = ULongToHandle(tid);
if (handle_ptr) *handle_ptr = handle;
else NtClose( handle );
diff --git a/dlls/winegstreamer/glibthread.c b/dlls/winegstreamer/glibthread.c
index 0d829a0..46e22f4 100644
--- a/dlls/winegstreamer/glibthread.c
+++ b/dlls/winegstreamer/glibthread.c
@@ -43,6 +43,7 @@
#include <stdlib.h>
#include <stdio.h>
+#if 0
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
@@ -388,3 +389,15 @@ void g_thread_impl_init (void)
g_thread_self_tls = TlsAlloc ();
g_thread_init(&g_thread_functions_for_glib_use_default);
}
+
+#else
+
+void g_thread_impl_init (void)
+{
+ static gboolean beenhere = FALSE;
+
+ if (!beenhere++)
+ g_thread_init(NULL);
+}
+
+#endif
diff --git a/libs/wine/loader.c b/libs/wine/loader.c
index 7261522..a8c31b9 100644
--- a/libs/wine/loader.c
+++ b/libs/wine/loader.c
@@ -73,6 +73,13 @@ char **__wine_main_argv = NULL;
WCHAR **__wine_main_wargv = NULL;
char **__wine_main_environ = NULL;
+#ifdef __linux__
+#include <pthread.h>
+typeof(pthread_create) *call_pthread_create, *__glob_pthread_create;
+typeof(pthread_join) *call_pthread_join, *__glob_pthread_join;
+typeof(pthread_detach) *call_pthread_detach, *__glob_pthread_detach;
+#endif
+
struct dll_path_context
{
unsigned int index; /* current index in the dll path list */
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 2159fac..fb3b951 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -117,6 +117,12 @@ WINE_1.0
wine_utf8_mbstowcs;
wine_utf8_wcstombs;
wine_wctype_table;
+ __glob_pthread_create;
+ call_pthread_create;
+ __glob_pthread_join;
+ call_pthread_join;
+ __glob_pthread_detach;
+ call_pthread_detach;
local: *;
};
diff --git a/loader/Makefile.in b/loader/Makefile.in
index 95e4798..a18dd02 100644
--- a/loader/Makefile.in
+++ b/loader/Makefile.in
@@ -1,4 +1,4 @@
-EXTRALIBS = $(PTHREAD_LIBS)
+EXTRALIBS = $(PTHREAD_LIBS) $(DL_LIBS)
C_SRCS = \
main.c \
diff --git a/loader/main.c b/loader/main.c
index ac67290..76609e1 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -202,6 +202,45 @@ static int pre_exec(void)
#endif
+#ifdef __linux__
+
+extern typeof(pthread_create) *call_pthread_create, *__glob_pthread_create;
+extern typeof(pthread_detach) *call_pthread_detach, *__glob_pthread_detach;
+extern typeof(pthread_join) *call_pthread_join, *__glob_pthread_join;
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine) (void *), void *arg)
+{
+ return call_pthread_create(thread, attr, start_routine, arg);
+}
+
+int pthread_detach(pthread_t thread)
+{
+ return call_pthread_detach(thread);
+}
+
+int pthread_join(pthread_t thread, void **retval)
+{
+ return call_pthread_join(thread, retval);
+}
+
+static void init_thread_hook(void) {
+ call_pthread_create = __glob_pthread_create = dlvsym(RTLD_NEXT, "pthread_create", "GLIBC_2.2.5");
+ if (!__glob_pthread_create)
+ call_pthread_create = __glob_pthread_create = dlvsym(RTLD_NEXT, "pthread_create", "GLIBC_2.1");
+
+ call_pthread_detach = __glob_pthread_detach = dlsym(RTLD_NEXT, "pthread_detach");
+ call_pthread_join = __glob_pthread_join = dlsym(RTLD_NEXT, "pthread_join");
+
+ /* Call a function from libpthread to ensure being linked against it */
+ pthread_yield();
+}
+
+#else
+
+#define init_thread_hook()
+
+#endif
/**********************************************************************
* main
@@ -211,6 +250,8 @@ int main( int argc, char *argv[] )
char error[1024];
int i;
+ init_thread_hook();
+
if (!getenv( "WINELOADERNOEXEC" )) /* first time around */
{
static char noexec[] = "WINELOADERNOEXEC=1";
--
1.7.6.6.GIT

View File

@ -0,0 +1,58 @@
From 695c19cdd2fc24aaa7ed89976c4965b376707131 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 25 Feb 2015 22:45:42 +0100
Subject: ntdll: Fix race-condition when threads are killed during shutdown.
When exit_thread is executed, nb_threads is decremented before the thread is
fully shutdown. When another thread runs ExitProcess() this will cause a SIGQUIT
signal to all threads, effectively decrementing nb_threads twice. The process
will terminate with a wrong exitcode then because the refcount reaches zero too
early.
Currently Wine has no locking protection of LdrShutdownProcess(), so it can
only be executed safely when all other threads have terminated before. Most
likely there are more Wine bugs in this area, but the attached patch should
fix the most critical one (messed up refcounting of threads) for now.
[Alexandre Rostovtsev <tetromino@gentoo.org> : rebase to be applied after
Maarten Lankhorst's "override pthreads to fix gstreamer v5" patch.]
---
dlls/ntdll/thread.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 4f181dc..1bdbcbf 100755
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -461,6 +461,7 @@ static void exit_thread_common( int status )
static void *prev_teb;
TEB *teb;
#endif
+ sigset_t sigset;
if (status) /* send the exit code to the server (0 is already the default) */
{
@@ -473,7 +474,7 @@ static void exit_thread_common( int status )
SERVER_END_REQ;
}
- if (interlocked_xchg_add( &nb_threads, -1 ) <= 1)
+ if (interlocked_xchg_add( &nb_threads, 0 ) <= 1)
{
LdrShutdownProcess();
exit( status );
@@ -499,6 +500,11 @@ static void exit_thread_common( int status )
reap_thread(NtCurrentTeb());
#endif
+ sigemptyset( &sigset );
+ sigaddset( &sigset, SIGQUIT );
+ pthread_sigmask( SIG_BLOCK, &sigset, NULL );
+ if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( status );
+
close( ntdll_get_thread_data()->wait_fd[0] );
close( ntdll_get_thread_data()->wait_fd[1] );
close( ntdll_get_thread_data()->reply_fd );
--
2.3.1

View File

@ -0,0 +1,48 @@
From 0d92921d264d5d0d1041c66353f022f1bc88577f Mon Sep 17 00:00:00 2001
From: Alexandre Rostovtsev <tetromino@gentoo.org>
Date: Sun, 8 Mar 2015 00:10:31 -0500
Subject: [PATCH] Revert "ntdll: Fix race-condition when threads are killed
during shutdown."
This reverts Sebastian Lackner's Wine-Staging patch to allow Maarten
Lankhorst's "override pthreads to fix gstreamer v5" to apply
---
dlls/ntdll/thread.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 74e64c9..3696c8e 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -370,7 +370,6 @@ void terminate_thread( int status )
void exit_thread( int status )
{
static void *prev_teb;
- sigset_t sigset;
TEB *teb;
if (status) /* send the exit code to the server (0 is already the default) */
@@ -384,7 +383,7 @@ void exit_thread( int status )
SERVER_END_REQ;
}
- if (interlocked_xchg_add( &nb_threads, 0 ) <= 1)
+ if (interlocked_xchg_add( &nb_threads, -1 ) <= 1)
{
LdrShutdownProcess();
exit( status );
@@ -406,11 +405,6 @@ void exit_thread( int status )
}
}
- sigemptyset( &sigset );
- sigaddset( &sigset, SIGQUIT );
- pthread_sigmask( SIG_BLOCK, &sigset, NULL );
- if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( status );
-
close( ntdll_get_thread_data()->wait_fd[0] );
close( ntdll_get_thread_data()->wait_fd[1] );
close( ntdll_get_thread_data()->reply_fd );
--
2.3.1

View File

@ -1,6 +1,6 @@
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/app-emulation/wine/wine-1.7.35.ebuild,v 1.1 2015/01/01 21:01:23 ryao Exp $
# $Header: /var/cvsroot/gentoo-x86/app-emulation/wine/wine-1.7.39.ebuild,v 1.1 2015/03/08 07:00:24 tetromino Exp $
EAPI="5"
@ -12,7 +12,8 @@ inherit autotools-utils eutils fdo-mime flag-o-matic gnome2-utils l10n multilib
if [[ ${PV} == "9999" ]] ; then
EGIT_REPO_URI="git://source.winehq.org/git/wine.git"
inherit git-2
EGIT_BRANCH="master"
inherit git-r3
SRC_URI=""
#KEYWORDS=""
else
@ -22,10 +23,12 @@ else
S=${WORKDIR}/${MY_P}
fi
GV="2.34"
MV="4.5.4"
COMPHOLIO_P="wine-staging-1.7.34"
WINE_GENTOO="wine-gentoo-2013.06.24"
GV="2.36"
MV="4.5.6"
STAGING_P="wine-staging-${PV}"
STAGING_DIR="${WORKDIR}/${STAGING_P}"
WINE_GENTOO="wine-gentoo-2015.03.07"
GST_P="wine-1.7.34-gstreamer-v5"
DESCRIPTION="Free implementation of Windows(tm) on Unix"
HOMEPAGE="http://www.winehq.org/"
SRC_URI="${SRC_URI}
@ -34,17 +37,27 @@ SRC_URI="${SRC_URI}
abi_x86_64? ( mirror://sourceforge/${PN}/Wine%20Gecko/${GV}/wine_gecko-${GV}-x86_64.msi )
)
mono? ( mirror://sourceforge/${PN}/Wine%20Mono/${MV}/wine-mono-${MV}.msi )
pipelight? ( https://github.com/wine-compholio/wine-staging/archive/v${PV}.tar.gz -> ${COMPHOLIO_P}.tar.gz )
pulseaudio? ( https://github.com/wine-compholio/wine-staging/archive/v${PV}.tar.gz -> ${COMPHOLIO_P}.tar.gz )
gstreamer? ( http://dev.gentoo.org/~tetromino/distfiles/${PN}/${GST_P}.patch.bz2 )
http://dev.gentoo.org/~tetromino/distfiles/${PN}/${WINE_GENTOO}.tar.bz2"
if [[ ${PV} == "9999" ]] ; then
STAGING_EGIT_REPO_URI="git://github.com/wine-compholio/wine-staging.git"
else
SRC_URI="${SRC_URI}
staging? ( https://github.com/wine-compholio/wine-staging/archive/v${PV}.tar.gz -> ${STAGING_P}.tar.gz )
pulseaudio? ( https://github.com/wine-compholio/wine-staging/archive/v${PV}.tar.gz -> ${STAGING_P}.tar.gz )"
fi
LICENSE="LGPL-2.1"
SLOT="0"
IUSE="+abi_x86_32 +abi_x86_64 +alsa capi cups custom-cflags dos elibc_glibc +fontconfig +gecko gphoto2 gsm gstreamer +jpeg lcms ldap +mono mp3 ncurses netapi nls odbc openal opencl +opengl osmesa oss +perl pcap pipelight +png +prelink pulseaudio +realtime +run-exes samba scanner selinux +ssl test +threads +truetype +udisks v4l +X xcomposite xinerama +xml"
IUSE="+abi_x86_32 +abi_x86_64 +alsa capi cups custom-cflags dos elibc_glibc +fontconfig +gecko gphoto2 gsm gstreamer +jpeg +lcms ldap +mono mp3 ncurses netapi nls odbc openal opencl +opengl osmesa oss +perl pcap pipelight +png +prelink pulseaudio +realtime +run-exes s3tc samba scanner selinux +ssl staging test +threads +truetype +udisks v4l vaapi +X +xcomposite xinerama +xml"
REQUIRED_USE="|| ( abi_x86_32 abi_x86_64 )
test? ( abi_x86_32 )
elibc_glibc? ( threads )
mono? ( abi_x86_32 )
pipelight? ( staging )
s3tc? ( staging )
vaapi? ( staging )
osmesa? ( opengl )" #286560
# FIXME: the test suite is unsuitable for us; many tests require net access
@ -85,13 +98,14 @@ NATIVE_DEPEND="
odbc? ( dev-db/unixODBC:= )
osmesa? ( media-libs/mesa[osmesa] )
pcap? ( net-libs/libpcap )
pipelight? ( sys-apps/attr )
staging? ( sys-apps/attr )
pulseaudio? ( media-sound/pulseaudio )
xml? ( dev-libs/libxml2 dev-libs/libxslt )
scanner? ( media-gfx/sane-backends:= )
ssl? ( net-libs/gnutls:= )
png? ( media-libs/libpng:0= )
v4l? ( media-libs/libv4l )
vaapi? ( x11-libs/libva[X] )
xcomposite? ( x11-libs/libXcomposite )"
COMMON_DEPEND="
@ -194,14 +208,14 @@ COMMON_DEPEND="
>=media-libs/mesa-9.1.6[osmesa,abi_x86_32(-)]
) )
pcap? ( net-libs/libpcap[abi_x86_32(-)] )
pipelight? ( || (
app-emulation/emul-linux-x86-baselibs[development,-abi_x86_32(-)]
>=sys-apps/attr-2.4.47-r1[abi_x86_32(-)]
) )
pulseaudio? ( || (
app-emulation/emul-linux-x86-soundlibs[development,-abi_x86_32(-)]
>=media-sound/pulseaudio-5.0[abi_x86_32(-)]
) )
staging? ( || (
app-emulation/emul-linux-x86-baselibs[development,-abi_x86_32(-)]
>=sys-apps/attr-2.4.47-r1[abi_x86_32(-)]
) )
xml? ( || (
>=app-emulation/emul-linux-x86-baselibs-20131008[development,-abi_x86_32(-)]
(
@ -225,6 +239,7 @@ COMMON_DEPEND="
app-emulation/emul-linux-x86-medialibs[development,-abi_x86_32(-)]
>=media-libs/libv4l-0.9.5[abi_x86_32(-)]
) )
vaapi? ( x11-libs/libva[X,abi_x86_32(-)] )
xcomposite? ( || (
app-emulation/emul-linux-x86-xlibs[development,-abi_x86_32(-)]
>=x11-libs/libXcomposite-0.4.4-r1[abi_x86_32(-)]
@ -235,13 +250,16 @@ COMMON_DEPEND="
RDEPEND="${COMMON_DEPEND}
dos? ( games-emulation/dosbox )
perl? ( dev-lang/perl dev-perl/XML-Simple )
s3tc? ( >=media-libs/libtxc_dxtn-1.0.1-r1[${MULTILIB_USEDEP}] )
samba? ( >=net-fs/samba-3.0.25 )
selinux? ( sec-policy/selinux-wine )
udisks? ( sys-fs/udisks:2 )
pulseaudio? ( realtime? ( sys-auth/rtkit ) )"
# tools/make_requests requires perl
DEPEND="${COMMON_DEPEND}
amd64? ( abi_x86_32? ( !abi_x86_64? ( ${NATIVE_DEPEND} ) ) )
staging? ( dev-lang/perl dev-perl/XML-Simple )
X? (
x11-proto/inputproto
x11-proto/xextproto
@ -288,62 +306,71 @@ pkg_setup() {
src_unpack() {
if [[ ${PV} == "9999" ]] ; then
git-2_src_unpack
git-r3_src_unpack
if use staging || use pulseaudio; then
EGIT_REPO_URI=${STAGING_EGIT_REPO_URI}
unset ${PN}_LIVE_REPO;
EGIT_CHECKOUT_DIR=${STAGING_DIR} git-r3_src_unpack
fi
else
unpack ${MY_P}.tar.bz2
use staging || use pulseaudio && unpack "${STAGING_P}.tar.gz"
fi
use pipelight || use pulseaudio && unpack "${COMPHOLIO_P}.tar.gz"
unpack "${WINE_GENTOO}.tar.bz2"
use gstreamer && unpack "${GST_P}.patch.bz2"
l10n_find_plocales_changes "${S}/po" "" ".po"
}
src_prepare() {
local md5="$(md5sum server/protocol.def)"
local f
local PATCHES=(
"${FILESDIR}"/${PN}-1.5.26-winegcc.patch #260726
"${FILESDIR}"/${PN}-1.4_rc2-multilib-portage.patch #395615
"${FILESDIR}"/${PN}-1.7.12-osmesa-check.patch #429386
"${FILESDIR}"/${PN}-1.6-memset-O3.patch #480508
)
local COMPHOLIO_MAKE_ARGS="-W fonts-Missing_Fonts.ok"
use pulseaudio || COMPHOLIO_MAKE_ARGS="${COMPHOLIO_MAKE_ARGS} -W winepulse-PulseAudio_Support.ok"
if use gstreamer; then
# See http://bugs.winehq.org/show_bug.cgi?id=30557
ewarn "Applying experimental patch to fix GStreamer support. Note that"
ewarn "this patch has been reported to cause crashes in certain games."
PATCHES+=( "${FILESDIR}/${PN}-1.7.28-gstreamer-v4.patch" )
# Wine-Staging 1.7.39 "ntdll: Fix race-condition when threads are killed
# during shutdown" patch prevents the gstreamer patch from applying cleanly.
# So undo the staging patch, apply gstreamer, then re-apply rebased staging
# patch on top.
if use staging; then
PATCHES+=(
"${FILESDIR}/${PN}-1.7.39-gstreamer-v5-staging-pre.patch"
"${WORKDIR}/${GST_P}.patch"
"${FILESDIR}/${PN}-1.7.39-gstreamer-v5-staging-post.patch" )
else
PATCHES+=( "${WORKDIR}/${GST_P}.patch" )
fi
fi
if use pipelight; then
ewarn "Applying the unofficial Compholio patchset for Pipelight support,"
ewarn "which is unsupported by Wine developers. Please don't report bugs"
ewarn "to Wine bugzilla unless you can reproduce them with USE=-pipelight"
if use staging; then
ewarn "Applying the unofficial Wine-Staging patchset which is unsupported"
ewarn "by Wine developers. Please don't report bugs to Wine bugzilla"
ewarn "unless you can reproduce them with USE=-staging"
# epatch doesn't support binary patches and we ship our own pulse patches
emake -C "${WORKDIR}/${COMPHOLIO_P}/patches" \
$(echo ${COMPHOLIO_MAKE_ARGS}) \
series
local STAGING_EXCLUDE=""
use pipelight || STAGING_EXCLUDE="${STAGING_EXCLUDE} -W Pipelight"
PATCHES+=( $(sed -e "s:^:${WORKDIR}/${COMPHOLIO_P}/patches/:" \
"${WORKDIR}/${COMPHOLIO_P}/patches/series") )
# epatch doesn't support binary patches
ebegin "Applying Compholio font patches"
for f in "${WORKDIR}/${COMPHOLIO_P}/patches/fonts-Missing_Fonts"/*.patch; do
"../${COMPHOLIO_P}/debian/tools/gitapply.sh" < "${f}" \
|| die "Failed to apply ${f}"
done
eend
# Launch wine-staging patcher in a subshell, using epatch as a backend, and gitapply.sh as a backend for binary patches
ebegin "Running Wine-Staging patch installer"
(
set -- DESTDIR="${S}" --backend=epatch --no-autoconf --all ${STAGING_EXCLUDE}
cd "${STAGING_DIR}/patches"
source "${STAGING_DIR}/patches/patchinstall.sh"
)
eend $?
elif use pulseaudio; then
PATCHES+=( "../${COMPHOLIO_P}/patches/winepulse-PulseAudio_Support"/*.patch )
PATCHES+=( "${STAGING_DIR}/patches/winepulse-PulseAudio_Support"/*.patch )
fi
autotools-utils_src_prepare
# Modification of the server protocol requires regenerating the server requests
if [[ "$(md5sum server/protocol.def)" != "${md5}" ]]; then
einfo "server/protocol.def was patched; running tools/make_requests"
tools/make_requests || die #432348
@ -405,8 +432,13 @@ multilib_src_configure() {
$(use_with xml xslt)
)
use pulseaudio && myconf+=( --with-pulse )
use pipelight && myconf+=( --with-xattr )
if use pulseaudio || use staging; then
myconf+=( $(use_with pulseaudio pulse) )
fi
use staging && myconf+=(
--with-xattr
$(use_with vaapi va)
)
local PKG_CONFIG AR RANLIB
# Avoid crossdev's i686-pc-linux-gnu-pkg-config if building wine32 on amd64; #472038
@ -465,7 +497,7 @@ multilib_src_install_all() {
insinto /usr/share/wine/mono
doins "${DISTDIR}"/wine-mono-${MV}.msi
fi
if ! use perl ; then
if ! use perl ; then # winedump calls function_grep.pl, and winemaker is a perl script
rm "${D}"usr/bin/{wine{dump,maker},function_grep.pl} "${D}"usr/share/man/man1/wine{dump,maker}.1 || die
fi