HANDLE cancel_event;
#endif
+ bool detached;
bool killable;
bool killed;
vlc_cleanup_t *cleaners;
case DLL_PROCESS_ATTACH:
vlc_mutex_init (&super_mutex);
vlc_cond_init (&super_variable);
- vlc_threadvar_create (&thread_key, free);
+ vlc_threadvar_create (&thread_key, NULL);
break;
case DLL_PROCESS_DETACH:
vlc_threadvar_set (thread_key, th);
th->killable = true;
- th->entry (th->data);
+ th->data = th->entry (th->data);
vlc_threadvar_cleanup ();
+ if (th->detached)
+ free (th);
return 0;
}
return ENOMEM;
th->entry = entry;
th->data = data;
+ th->detached = p_handle == NULL;
th->killable = false; /* not until vlc_entry() ! */
th->killed = false;
th->cleaners = NULL;
}
#else
+ /* FIXME: cancel_event is useless and leaked in detached threads */
th->cancel_event = CreateEvent (NULL, FALSE, FALSE, NULL);
if (th->cancel_event == NULL)
{
#endif
th->id = hThread;
- *p_handle = th;
ResumeThread (hThread);
if (priority)
SetThreadPriority (hThread, priority);
+ if (p_handle != NULL)
+ *p_handle = th;
+ else
+ CloseHandle (hThread);
+
return 0;
}
== WAIT_IO_COMPLETION);
CloseHandle (th->id);
- assert (result == NULL); /* <- FIXME if ever needed */
#ifdef UNDER_CE
CloseHandle (th->cancel_event);
#endif
+ if (result != NULL)
+ *result = th->data;
+ free (th);
}
-int vlc_clone_detach (vlc_thread_t *p_handle, void *(*entry) (void *),
- void *data, int priority)
+int vlc_clone_detach (void *(*entry) (void *), void *data, int priority)
{
- vlc_thread_t th;
- if (p_handle == NULL)
- p_handle = &th;
-
- int ret = vlc_clone (p_handle, entry, data, priority);
- if (ret)
- return ret;
-
- /* FIXME: handle->cancel_event leak UNDER_CE */
- CloseHandle ((*p_handle)->id);
- return 0;
+ return vlc_clone (NULL, entry, data, priority);
}
/*** Thread cancellation ***/
if (th->killable && th->killed)
{
+ /* Detached threads cannot be cancelled */
+ assert (!th->detached);
+
+ th->data = NULL; /* TODO: special value? */
+
for (vlc_cleanup_t *p = th->cleaners; p != NULL; p = p->next)
p->proc (p->data);
vlc_threadvar_cleanup ();