Changeset a9e4de11cbbb54c4fdc9fa16f5adfdfd30e57fcf
- Timestamp:
- 18/08/07 13:03:04
(1 year ago)
- Author:
- Damien Fouilleul <damienf@videolan.org>
- git-committer:
- Damien Fouilleul <damienf@videolan.org> 1187434984 +0000
- git-parent:
[1144af45baae4cbc6609c46d771f314ce84ddcef]
- git-author:
- Damien Fouilleul <damienf@videolan.org> 1187434984 +0000
- Message:
threads: win32, make sure only object owning a thread can close its handle when object is destroyed
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r2ff0745 |
ra9e4de1 |
|
| 167 | 167 | |
|---|
| 168 | 168 | #elif defined( WIN32 ) || defined( UNDER_CE ) |
|---|
| 169 | | typedef HANDLE vlc_thread_t; |
|---|
| | 169 | typedef struct |
|---|
| | 170 | { |
|---|
| | 171 | /* thread id */ |
|---|
| | 172 | DWORD id; |
|---|
| | 173 | /* |
|---|
| | 174 | ** handle to created thread, needs be closed to dispose of it |
|---|
| | 175 | ** even after thread has exited |
|---|
| | 176 | */ |
|---|
| | 177 | HANDLE hThread; |
|---|
| | 178 | } vlc_thread_t; |
|---|
| | 179 | |
|---|
| 170 | 180 | typedef BOOL (WINAPI *SIGNALOBJECTANDWAIT) ( HANDLE, HANDLE, DWORD, BOOL ); |
|---|
| 171 | | typedef unsigned (WINAPI *PTHREAD_START) (void *); |
|---|
| 172 | 181 | |
|---|
| 173 | 182 | typedef struct |
|---|
| rbe50cf5 |
ra9e4de1 |
|
| 425 | 425 | vlc_mutex_unlock( &structure_lock ); |
|---|
| 426 | 426 | } |
|---|
| | 427 | |
|---|
| | 428 | #if defined(WIN32) || defined(UNDER_CE) |
|---|
| | 429 | /* if object has an associated thread, close it now */ |
|---|
| | 430 | if( p_priv->thread_id.hThread ) |
|---|
| | 431 | CloseHandle(p_priv->thread_id.hThread); |
|---|
| | 432 | #endif |
|---|
| 427 | 433 | |
|---|
| 428 | 434 | vlc_mutex_destroy( &p_this->object_lock ); |
|---|
| … | … | |
| 1210 | 1216 | if( p_this->p_internals->b_thread ) |
|---|
| 1211 | 1217 | snprintf( psz_thread, 29, " (thread %u)", |
|---|
| | 1218 | #if defined(WIN32) || defined(UNDER_CE) |
|---|
| | 1219 | (unsigned)p_this->p_internals->thread_id.id ); |
|---|
| | 1220 | #else |
|---|
| 1212 | 1221 | (unsigned)p_this->p_internals->thread_id ); |
|---|
| | 1222 | #endif |
|---|
| 1213 | 1223 | |
|---|
| 1214 | 1224 | psz_parent[0] = '\0'; |
|---|
| r84098a5 |
ra9e4de1 |
|
| 553 | 553 | } |
|---|
| 554 | 554 | |
|---|
| 555 | | #if defined( WIN32 ) || defined( UNDER_CE ) |
|---|
| 556 | | |
|---|
| 557 | | /* |
|---|
| 558 | | ** Use a wrapper function which will make sure that |
|---|
| 559 | | ** thread handle is closed |
|---|
| 560 | | */ |
|---|
| 561 | | struct _vlc_win32_init_thread_data { |
|---|
| 562 | | void * ( *func ) (void * ); |
|---|
| 563 | | void *p_data; |
|---|
| 564 | | }; |
|---|
| 565 | | |
|---|
| 566 | | static unsigned WINAPI __vlc_win32_thread_start(void* p_data) { |
|---|
| 567 | | struct _vlc_win32_init_thread_data *p_win32data = |
|---|
| 568 | | (struct _vlc_win32_init_thread_data *)p_data; |
|---|
| 569 | | vlc_object_t *p_this = (vlc_object_t *)p_win32data->p_data; |
|---|
| 570 | | HANDLE hThread = (HANDLE)p_this->p_internals->thread_id; |
|---|
| 571 | | void *retval = (*p_win32data->func)((LPVOID)p_this); |
|---|
| 572 | | CloseHandle(hThread); |
|---|
| 573 | | return (unsigned)retval; |
|---|
| 574 | | } |
|---|
| 575 | | |
|---|
| 576 | | #endif |
|---|
| 577 | | |
|---|
| 578 | 555 | /***************************************************************************** |
|---|
| 579 | 556 | * vlc_thread_create: create a thread, inner version |
|---|
| … | … | |
| 589 | 566 | void *p_data = (void *)p_this; |
|---|
| 590 | 567 | vlc_object_internals_t *p_priv = p_this->p_internals; |
|---|
| 591 | | #if defined( WIN32 ) || defined( UNDER_CE ) |
|---|
| 592 | | struct _vlc_win32_init_thread_data win32data = { func, p_data }; |
|---|
| 593 | | #endif |
|---|
| 594 | 568 | |
|---|
| 595 | 569 | vlc_mutex_lock( &p_this->object_lock ); |
|---|
| … | … | |
| 605 | 579 | #elif defined( WIN32 ) || defined( UNDER_CE ) |
|---|
| 606 | 580 | { |
|---|
| 607 | | unsigned threadID; |
|---|
| 608 | 581 | /* When using the MSVCRT C library you have to use the _beginthreadex |
|---|
| 609 | 582 | * function instead of CreateThread, otherwise you'll end up with |
|---|
| … | … | |
| 611 | 584 | * Knowledge Base, article 104641) */ |
|---|
| 612 | 585 | #if defined( UNDER_CE ) |
|---|
| 613 | | HANDLE hThread = CreateThread( NULL, 0, __vlc_win32_thread_start, |
|---|
| 614 | | (LPVOID)&win32data, 0, &threadID ); |
|---|
| | 586 | DWORD threadId; |
|---|
| | 587 | HANDLE hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)func, |
|---|
| | 588 | (LPVOID)p_data, CREATE_SUSPENDED, |
|---|
| | 589 | &threadId ); |
|---|
| 615 | 590 | #else |
|---|
| 616 | | uintptr_t hThread = _beginthreadex( NULL, 0, __vlc_win32_thread_start, |
|---|
| 617 | | (void*)&win32data, 0, &threadID ); |
|---|
| 618 | | #endif |
|---|
| 619 | | p_priv->thread_id = (HANDLE)hThread; |
|---|
| 620 | | } |
|---|
| 621 | | |
|---|
| 622 | | if( p_priv->thread_id && i_priority ) |
|---|
| 623 | | { |
|---|
| 624 | | if( !SetThreadPriority(p_priv->thread_id, i_priority) ) |
|---|
| | 591 | unsigned threadId; |
|---|
| | 592 | uintptr_t hThread = _beginthreadex( NULL, 0, |
|---|
| | 593 | (LPTHREAD_START_ROUTINE)func, |
|---|
| | 594 | (void*)p_data, CREATE_SUSPENDED, |
|---|
| | 595 | &threadId ); |
|---|
| | 596 | #endif |
|---|
| | 597 | p_priv->thread_id.id = (DWORD)threadId; |
|---|
| | 598 | p_priv->thread_id.hThread = (HANDLE)hThread; |
|---|
| | 599 | ResumeThread((HANDLE)hThread); |
|---|
| | 600 | } |
|---|
| | 601 | |
|---|
| | 602 | i_ret = ( p_priv->thread_id.hThread ? 0 : 1 ); |
|---|
| | 603 | |
|---|
| | 604 | if( i_ret && i_priority ) |
|---|
| | 605 | { |
|---|
| | 606 | if( !SetThreadPriority(p_priv->thread_id.hThread, i_priority) ) |
|---|
| 625 | 607 | { |
|---|
| 626 | 608 | msg_Warn( p_this, "couldn't set a faster priority" ); |
|---|
| … | … | |
| 628 | 610 | } |
|---|
| 629 | 611 | } |
|---|
| 630 | | |
|---|
| 631 | | i_ret = ( p_priv->thread_id ? 0 : 1 ); |
|---|
| 632 | 612 | |
|---|
| 633 | 613 | #elif defined( HAVE_KERNEL_SCHEDULER_H ) |
|---|
| … | … | |
| 692 | 672 | p_priv->b_thread = VLC_TRUE; |
|---|
| 693 | 673 | |
|---|
| | 674 | #if defined( WIN32 ) || defined( UNDER_CE ) |
|---|
| | 675 | msg_Dbg( p_this, "thread %u (%s) created at priority %d (%s:%d)", |
|---|
| | 676 | (unsigned int)p_priv->thread_id.id, psz_name, |
|---|
| | 677 | i_priority, psz_file, i_line ); |
|---|
| | 678 | #else |
|---|
| 694 | 679 | msg_Dbg( p_this, "thread %u (%s) created at priority %d (%s:%d)", |
|---|
| 695 | 680 | (unsigned int)p_priv->thread_id, psz_name, i_priority, |
|---|
| 696 | 681 | psz_file, i_line ); |
|---|
| | 682 | #endif |
|---|
| | 683 | |
|---|
| 697 | 684 | |
|---|
| 698 | 685 | vlc_mutex_unlock( &p_this->object_lock ); |
|---|
| … | … | |
| 718 | 705 | #if defined( PTH_INIT_IN_PTH_H ) || defined( ST_INIT_IN_ST_H ) |
|---|
| 719 | 706 | #elif defined( WIN32 ) || defined( UNDER_CE ) |
|---|
| 720 | | if( !p_priv->thread_id ) |
|---|
| 721 | | p_priv->thread_id = GetCurrentThread(); |
|---|
| 722 | | if( !SetThreadPriority((HANDLE)p_priv->thread_id, i_priority) ) |
|---|
| | 707 | if( !p_priv->thread_id.hThread ) |
|---|
| | 708 | p_priv->thread_id.hThread = GetCurrentThread(); |
|---|
| | 709 | if( !SetThreadPriority(p_priv->thread_id.hThread, i_priority) ) |
|---|
| 723 | 710 | { |
|---|
| 724 | 711 | msg_Warn( p_this, "couldn't set a faster priority" ); |
|---|
| … | … | |
| 780 | 767 | { |
|---|
| 781 | 768 | vlc_object_internals_t *p_priv = p_this->p_internals; |
|---|
| 782 | | int i_ret = 0; |
|---|
| 783 | | |
|---|
| 784 | | #if defined( PTH_INIT_IN_PTH_H ) |
|---|
| 785 | | i_ret = ( pth_join( p_priv->thread_id, NULL ) == FALSE ); |
|---|
| 786 | | |
|---|
| 787 | | #elif defined( ST_INIT_IN_ST_H ) |
|---|
| 788 | | i_ret = st_thread_join( p_priv->thread_id, NULL ); |
|---|
| 789 | | |
|---|
| 790 | | #elif defined( UNDER_CE ) || defined( WIN32 ) |
|---|
| | 769 | |
|---|
| | 770 | #if defined( UNDER_CE ) || defined( WIN32 ) |
|---|
| 791 | 771 | HMODULE hmodule; |
|---|
| 792 | 772 | BOOL (WINAPI *OurGetThreadTimes)( HANDLE, FILETIME*, FILETIME*, |
|---|
| … | … | |
| 796 | 776 | HANDLE hThread; |
|---|
| 797 | 777 | |
|---|
| 798 | | /* thread will destroy its own handle on exit, duplicate it here */ |
|---|
| | 778 | /* |
|---|
| | 779 | ** object will close its thread handle when destroyed, duplicate it here |
|---|
| | 780 | ** to be on the safe side |
|---|
| | 781 | */ |
|---|
| 799 | 782 | if( ! DuplicateHandle(GetCurrentProcess(), |
|---|
| 800 | | (HANDLE)p_priv->thread_id, |
|---|
| | 783 | p_priv->thread_id.hThread, |
|---|
| 801 | 784 | GetCurrentProcess(), |
|---|
| 802 | 785 | &hThread, |
|---|
| … | … | |
| 806 | 789 | { |
|---|
| 807 | 790 | msg_Err( p_this, "thread_join(%u) failed at %s:%d (%s)", |
|---|
| 808 | | (unsigned int)p_priv->thread_id, psz_file, i_line, |
|---|
| 809 | | GetLastError() ); |
|---|
| | 791 | (unsigned int)p_priv->thread_id.id, |
|---|
| | 792 | psz_file, i_line, GetLastError() ); |
|---|
| 810 | 793 | p_priv->b_thread = VLC_FALSE; |
|---|
| 811 | 794 | return; |
|---|
| … | … | |
| 814 | 797 | WaitForSingleObject( hThread, INFINITE ); |
|---|
| 815 | 798 | |
|---|
| | 799 | msg_Dbg( p_this, "thread %u joined (%s:%d)", |
|---|
| | 800 | (unsigned int)p_priv->thread_id.id, |
|---|
| | 801 | psz_file, i_line ); |
|---|
| 816 | 802 | #if defined( UNDER_CE ) |
|---|
| 817 | 803 | hmodule = GetModuleHandle( _T("COREDLL") ); |
|---|
| … | … | |
| 851 | 837 | CloseHandle( hThread ); |
|---|
| 852 | 838 | |
|---|
| | 839 | #else /* !defined(WIN32) */ |
|---|
| | 840 | |
|---|
| | 841 | int i_ret = 0; |
|---|
| | 842 | |
|---|
| | 843 | #if defined( PTH_INIT_IN_PTH_H ) |
|---|
| | 844 | i_ret = ( pth_join( p_priv->thread_id, NULL ) == FALSE ); |
|---|
| | 845 | |
|---|
| | 846 | #elif defined( ST_INIT_IN_ST_H ) |
|---|
| | 847 | i_ret = st_thread_join( p_priv->thread_id, NULL ); |
|---|
| | 848 | |
|---|
| 853 | 849 | #elif defined( HAVE_KERNEL_SCHEDULER_H ) |
|---|
| 854 | 850 | int32_t exit_value; |
|---|
| 855 | | wait_for_thread( p_priv->thread_id, &exit_value ); |
|---|
| | 851 | i_ret = (B_OK == wait_for_thread( p_priv->thread_id, &exit_value )); |
|---|
| 856 | 852 | |
|---|
| 857 | 853 | #elif defined( PTHREAD_COND_T_IN_PTHREAD_H ) |
|---|
| … | … | |
| 876 | 872 | } |
|---|
| 877 | 873 | |
|---|
| | 874 | #endif |
|---|
| | 875 | |
|---|
| 878 | 876 | p_priv->b_thread = VLC_FALSE; |
|---|
| 879 | 877 | } |
|---|
| rbe50cf5 |
ra9e4de1 |
|
| 1449 | 1449 | vlc_object_release( p_this->p_input ); |
|---|
| 1450 | 1450 | |
|---|
| 1451 | | #ifdef WIN32 |
|---|
| 1452 | | CloseHandle( p_this->p_internals->thread_id ); |
|---|
| 1453 | | #endif |
|---|
| 1454 | | |
|---|
| 1455 | 1451 | vlc_object_destroy( p_this ); |
|---|
| 1456 | 1452 | } |
|---|