3 Copyright (c) 2003-2015 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
11 #define _WIN32_WINNT 0x600
23 #include <kernel/OS.h>
26 #if defined(SYS_DARWIN) || defined(SYS_FREEBSD)
27 #include <sys/types.h>
28 #include <sys/sysctl.h>
32 #include <sys/param.h>
33 #include <sys/sysctl.h>
34 #include <machine/cpu.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
44 #include <netinet/in.h>
61 #include <sys/processor.h>
68 #if defined( SYS_LINUX )
69 #include <linux/cdrom.h>
71 #include <sys/ioctl.h>
72 #elif defined( SYS_OPENBSD )
73 #include <sys/dvdio.h>
75 #include <sys/ioctl.h>
79 #include <IOKit/pwr_mgt/IOPMLib.h>
86 #include "libavutil/cpu.h"
88 /************************************************************************
90 ************************************************************************
91 * Returns the current date in milliseconds.
92 * On Win32, we implement a gettimeofday emulation here because
93 * libdvdread and libmp4v2 use it without checking.
94 ************************************************************************/
101 int gettimeofday( struct timeval * tv, struct timezone * tz )
104 tick = GetTickCount();
105 tv->tv_sec = tick / 1000;
106 tv->tv_usec = ( tick % 1000 ) * 1000;
112 // Convert utf8 string to current code page.
113 // The internal string representation in hb is utf8. But some
114 // libraries (libmkv, and mp4v2) expect filenames in the current
115 // code page. So we must convert.
116 char * hb_utf8_to_cp(const char *src
)
120 #if defined( SYS_MINGW )
121 int num_chars
= MultiByteToWideChar(CP_UTF8
, 0, src
, -1, NULL
, 0);
124 wchar_t * tmp
= calloc(num_chars
, sizeof(wchar_t));
125 MultiByteToWideChar(CP_UTF8
, 0, src
, -1, tmp
, num_chars
);
126 int len
= WideCharToMultiByte(GetACP(), 0, tmp
, num_chars
, NULL
, 0, NULL
, NULL
);
129 dst
= calloc(len
, sizeof(char));
130 WideCharToMultiByte(GetACP(), 0, tmp
, num_chars
, dst
, len
, NULL
, NULL
);
133 // Other platforms don't have code pages
140 int hb_dvd_region(char *device
, int *region_mask
)
142 #if defined( DVD_LU_SEND_RPC_STATE ) && defined( DVD_AUTH )
147 fd
= open( device
, O_RDONLY
);
150 if ( fstat( fd
, &st
) < 0 )
155 if ( !( S_ISBLK( st
.st_mode
) || S_ISCHR( st
.st_mode
) ) )
161 ai
.type
= DVD_LU_SEND_RPC_STATE
;
162 ret
= ioctl(fd
, DVD_AUTH
, &ai
);
167 *region_mask
= ai
.lrpcs
.region_mask
;
174 uint64_t hb_get_date()
177 gettimeofday( &tv
, NULL
);
178 return( (uint64_t) tv
.tv_sec
* 1000 + (uint64_t) tv
.tv_usec
/ 1000 );
181 uint64_t hb_get_time_us()
184 static LARGE_INTEGER frequency
;
185 LARGE_INTEGER cur_time
;
187 if (frequency
.QuadPart
== 0)
189 QueryPerformanceFrequency(&frequency
);
192 QueryPerformanceCounter(&cur_time
);
194 return (uint64_t)(1000000 * cur_time
.QuadPart
/ frequency
.QuadPart
);
197 gettimeofday(&tv
, NULL
);
198 return ((uint64_t)tv
.tv_sec
* 1000000 + (uint64_t)tv
.tv_usec
);
202 /************************************************************************
204 ************************************************************************
205 * Waits <delay> milliseconds.
206 ************************************************************************/
207 void hb_snooze( int delay
)
213 #if defined( SYS_BEOS )
214 snooze( 1000 * delay
);
215 #elif defined( SYS_DARWIN ) || defined( SYS_LINUX ) || defined( SYS_FREEBSD) || defined( SYS_SunOS )
216 usleep( 1000 * delay
);
217 #elif defined( SYS_CYGWIN ) || defined( SYS_MINGW )
222 /************************************************************************
223 * Get information about the CPU (number of cores, name, platform name)
224 ************************************************************************/
225 static void init_cpu_info();
226 static int init_cpu_count();
229 enum hb_cpu_platform platform
;
239 int hb_get_cpu_count()
241 return hb_cpu_info
.count
;
244 int hb_get_cpu_platform()
246 return hb_cpu_info
.platform
;
249 const char* hb_get_cpu_name()
251 return hb_cpu_info
.name
;
254 const char* hb_get_cpu_platform_name()
256 switch (hb_cpu_info
.platform
)
258 // Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 3C
259 // Table 35-1: CPUID Signature Values of DisplayFamily_DisplayModel
260 case HB_CPU_PLATFORM_INTEL_BNL
:
261 return "Intel microarchitecture Bonnell";
262 case HB_CPU_PLATFORM_INTEL_SNB
:
263 return "Intel microarchitecture Sandy Bridge";
264 case HB_CPU_PLATFORM_INTEL_IVB
:
265 return "Intel microarchitecture Ivy Bridge";
266 case HB_CPU_PLATFORM_INTEL_SLM
:
267 return "Intel microarchitecture Silvermont";
268 case HB_CPU_PLATFORM_INTEL_HSW
:
269 return "Intel microarchitecture Haswell";
270 case HB_CPU_PLATFORM_INTEL_BDW
:
271 return "Intel microarchitecture Broadwell";
272 case HB_CPU_PLATFORM_INTEL_CHT
:
273 return "Intel microarchitecture Airmont";
286 #endif // ARCH_X86_32
288 #if ARCH_X86_64 || ARCH_X86_32
289 #define cpuid(index, eax, ebx, ecx, edx) \
291 "mov %%"REG_b", %%"REG_S" \n\t" \
293 "xchg %%"REG_b", %%"REG_S \
294 : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) \
296 #endif // ARCH_X86_64 || ARCH_X86_32
298 static void init_cpu_info()
300 hb_cpu_info
.name
= NULL
;
301 hb_cpu_info
.count
= init_cpu_count();
302 hb_cpu_info
.platform
= HB_CPU_PLATFORM_UNSPECIFIED
;
304 if (av_get_cpu_flags() & AV_CPU_FLAG_SSE
)
306 #if ARCH_X86_64 || ARCH_X86_32
307 int eax
, ebx
, ecx
, edx
, family
, model
;
309 cpuid(1, &eax
, &ebx
, &ecx
, &edx
);
310 family
= ((eax
>> 8) & 0xf) + ((eax
>> 20) & 0xff);
311 model
= ((eax
>> 4) & 0xf) + ((eax
>> 12) & 0xf0);
313 // Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 3C
314 // Table 35-1: CPUID Signature Values of DisplayFamily_DisplayModel
326 hb_cpu_info
.platform
= HB_CPU_PLATFORM_INTEL_BNL
;
330 hb_cpu_info
.platform
= HB_CPU_PLATFORM_INTEL_SNB
;
334 hb_cpu_info
.platform
= HB_CPU_PLATFORM_INTEL_IVB
;
341 hb_cpu_info
.platform
= HB_CPU_PLATFORM_INTEL_SLM
;
347 hb_cpu_info
.platform
= HB_CPU_PLATFORM_INTEL_HSW
;
352 hb_cpu_info
.platform
= HB_CPU_PLATFORM_INTEL_BDW
;
355 hb_cpu_info
.platform
= HB_CPU_PLATFORM_INTEL_CHT
;
366 // Intel 64 and IA-32 Architectures Software Developer's Manual, Vol. 2A
367 // Figure 3-8: Determination of Support for the Processor Brand String
368 // Table 3-17: Information Returned by CPUID Instruction
369 cpuid(0x80000000, &eax
, &ebx
, &ecx
, &edx
);
370 if ((eax
& 0x80000004) < 0x80000004)
373 &hb_cpu_info
.buf4
[ 0],
374 &hb_cpu_info
.buf4
[ 1],
375 &hb_cpu_info
.buf4
[ 2],
376 &hb_cpu_info
.buf4
[ 3]);
378 &hb_cpu_info
.buf4
[ 4],
379 &hb_cpu_info
.buf4
[ 5],
380 &hb_cpu_info
.buf4
[ 6],
381 &hb_cpu_info
.buf4
[ 7]);
383 &hb_cpu_info
.buf4
[ 8],
384 &hb_cpu_info
.buf4
[ 9],
385 &hb_cpu_info
.buf4
[10],
386 &hb_cpu_info
.buf4
[11]);
388 hb_cpu_info
.name
= hb_cpu_info
.buf
;
389 hb_cpu_info
.buf
[47] = '\0'; // just in case
391 while (isspace(*hb_cpu_info
.name
))
393 // skip leading whitespace to prettify
397 #endif // ARCH_X86_64 || ARCH_X86_32
402 * Whenever possible, returns the number of CPUs on the current computer.
403 * Returns 1 otherwise.
405 static int init_cpu_count()
409 #if defined(SYS_CYGWIN) || defined(SYS_MINGW)
411 GetSystemInfo( &cpuinfo
);
412 cpu_count
= cpuinfo
.dwNumberOfProcessors
;
414 #elif defined(SYS_LINUX)
417 memset( &p_aff
, 0, sizeof(p_aff
) );
418 sched_getaffinity( 0, sizeof(p_aff
), &p_aff
);
419 for( cpu_count
= 0, bit
= 0; bit
< sizeof(p_aff
); bit
++ )
420 cpu_count
+= (((uint8_t *)&p_aff
)[bit
/ 8] >> (bit
% 8)) & 1;
422 #elif defined(SYS_BEOS)
424 get_system_info( &info
);
425 cpu_count
= info
.cpu_count
;
427 #elif defined(SYS_DARWIN) || defined(SYS_FREEBSD) || defined(SYS_OPENBSD)
428 size_t length
= sizeof( cpu_count
);
430 int mib
[2] = { CTL_HW
, HW_NCPU
};
431 if( sysctl(mib
, 2, &cpu_count
, &length
, NULL
, 0) )
433 if( sysctlbyname("hw.ncpu", &cpu_count
, &length
, NULL
, 0) )
439 #elif defined( SYS_SunOS )
441 processorid_t cpumax
;
444 cpumax
= sysconf(_SC_CPUID_MAX
);
446 for(i
= 0; i
<= cpumax
; i
++ )
448 if(p_online(i
, P_STATUS
) != -1)
457 cpu_count
= MAX( 1, cpu_count
);
458 cpu_count
= MIN( cpu_count
, 64 );
463 int hb_platform_init()
467 #if defined(SYS_MINGW) && defined(PTW32_STATIC_LIB)
468 result
= !pthread_win32_process_attach_np();
471 hb_error("pthread_win32_process_attach_np() failed!");
476 #if defined(_WIN32) || defined(__MINGW32__)
478 * win32 _IOLBF (line-buffering) is the same as _IOFBF (full-buffering).
479 * force it to unbuffered otherwise informative output is not easily parsed.
481 result
= setvbuf(stdout
, NULL
, _IONBF
, 0);
484 hb_error("setvbuf(stdout, NULL, _IONBF, 0) failed!");
487 result
= setvbuf(stderr
, NULL
, _IONBF
, 0);
490 hb_error("setvbuf(stderr, NULL, _IONBF, 0) failed!");
500 /************************************************************************
501 * Get app data config directory
502 ***********************************************************************/
503 void hb_get_user_config_directory( char path
[512] )
505 /* Create the base */
506 #if defined( SYS_CYGWIN ) || defined( SYS_MINGW )
507 #ifndef CSIDL_FLAG_DONT_UNEXPAND
509 * XXX: some old MinGW toolchains don't have SHGetKnownFolderPath.
511 * SHGetFolderPath is deprecated, but this should be no problem in practice.
513 * Note: explicitly call the Unicode/WCHAR function SHGetFolderPathW.
515 WCHAR wide_path
[MAX_PATH
];
517 if (SHGetFolderPathW(NULL
, CSIDL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, wide_path
) == S_OK
&&
518 WideCharToMultiByte(CP_UTF8
, 0, wide_path
, -1, path
, 512, NULL
, NULL
) != 0)
526 if (SHGetKnownFolderPath(&FOLDERID_RoamingAppData
, 0, NULL
, &wide_path
) == S_OK
&&
527 WideCharToMultiByte(CP_UTF8
, 0, wide_path
, -1, path
, 512, NULL
, NULL
) != 0)
529 CoTaskMemFree(wide_path
);
533 else if (wide_path
!= NULL
)
535 CoTaskMemFree(wide_path
);
537 #endif // !defined CSIDL_FLAG_DONT_UNEXPAND
538 #elif defined( SYS_LINUX )
541 if ((p
= getenv("XDG_CONFIG_HOME")) != NULL
)
543 strncpy(path
, p
, 511);
547 else if ((p
= getenv("HOME")) != NULL
)
549 strncpy(path
, p
, 511);
551 int len
= strlen(path
);
552 strncpy(path
+ len
, "/.config", 511 - len
- 1);
556 #elif defined( __APPLE__ )
557 if (osx_get_user_config_directory(path
) == 0)
563 hb_error("Failed to lookup user config directory!");
567 /************************************************************************
568 * Get a user config filename for HB
569 ***********************************************************************/
570 void hb_get_user_config_filename( char name
[1024], char *fmt
, ... )
574 hb_get_user_config_directory( name
);
575 #if defined( SYS_CYGWIN ) || defined( SYS_MINGW )
576 strcat( name
, "\\" );
581 va_start( args
, fmt
);
582 vsnprintf( &name
[strlen(name
)], 1024 - strlen(name
), fmt
, args
);
586 /************************************************************************
587 * Get a temporary directory for HB
588 ***********************************************************************/
589 void hb_get_temporary_directory( char path
[512] )
594 /* Create the base */
595 #if defined( SYS_CYGWIN ) || defined( SYS_MINGW )
596 int i_size
= GetTempPath( 512, base
);
597 if( i_size
<= 0 || i_size
>= 512 )
599 if( getcwd( base
, 512 ) == NULL
)
600 strcpy( base
, "c:" ); /* Bad fallback but ... */
603 /* c:/path/ works like a charm under cygwin(win32?) so use it */
604 while( ( p
= strchr( base
, '\\' ) ) )
607 if( (p
= getenv( "TMPDIR" ) ) != NULL
||
608 (p
= getenv( "TEMP" ) ) != NULL
)
611 strcpy( base
, "/tmp" );
613 /* I prefer to remove evntual last '/' (for cygwin) */
614 if( base
[strlen(base
)-1] == '/' )
615 base
[strlen(base
)-1] = '\0';
617 snprintf(path
, 512, "%s/hb.%d", base
, (int)getpid());
620 /************************************************************************
621 * Get a tempory filename for HB
622 ***********************************************************************/
623 void hb_get_tempory_filename( hb_handle_t
* h
, char name
[1024],
628 hb_get_temporary_directory( name
);
631 va_start( args
, fmt
);
632 vsnprintf( &name
[strlen(name
)], 1024 - strlen(name
), fmt
, args
);
636 /************************************************************************
638 ************************************************************************
639 * Wrapper to the real stat, needed to handle utf8 filenames on
641 ***********************************************************************/
642 int hb_stat(const char *path
, hb_stat_t
*sb
)
645 wchar_t path_utf16
[MAX_PATH
];
646 if (!MultiByteToWideChar(CP_UTF8
, 0, path
, -1, path_utf16
, MAX_PATH
))
648 return _wstat64( path_utf16
, sb
);
650 return stat(path
, sb
);
654 /************************************************************************
656 ************************************************************************
657 * Wrapper to the real fopen, needed to handle utf8 filenames on
659 ***********************************************************************/
660 FILE * hb_fopen(const char *path
, const char *mode
)
664 wchar_t path_utf16
[MAX_PATH
];
665 wchar_t mode_utf16
[16];
666 if (!MultiByteToWideChar(CP_UTF8
, 0, path
, -1, path_utf16
, MAX_PATH
))
668 if (!MultiByteToWideChar(CP_UTF8
, 0, mode
, -1, mode_utf16
, 16))
670 errno_t ret
= _wfopen_s(&f
, path_utf16
, mode_utf16
);
675 return fopen(path
, mode
);
679 HB_DIR
* hb_opendir(char *path
)
683 wchar_t path_utf16
[MAX_PATH
];
685 if (!MultiByteToWideChar(CP_UTF8
, 0, path
, -1, path_utf16
, MAX_PATH
))
687 dir
= malloc(sizeof(HB_DIR
));
690 dir
->wdir
= _wopendir(path_utf16
);
691 if (dir
->wdir
== NULL
)
698 return opendir(path
);
702 int hb_closedir(HB_DIR
*dir
)
707 ret
= _wclosedir(dir
->wdir
);
711 return closedir(dir
);
715 struct dirent
* hb_readdir(HB_DIR
*dir
)
718 struct _wdirent
*entry
;
719 entry
= _wreaddir(dir
->wdir
);
723 int len
= WideCharToMultiByte(CP_UTF8
, 0, entry
->d_name
, -1,
724 dir
->entry
.d_name
, sizeof(dir
->entry
.d_name
),
726 dir
->entry
.d_ino
= entry
->d_ino
;
727 dir
->entry
.d_reclen
= entry
->d_reclen
;
728 dir
->entry
.d_namlen
= len
- 1;
735 void hb_rewinddir(HB_DIR
*dir
)
738 _wrewinddir(dir
->wdir
);
740 return rewinddir(dir
);
744 char * hb_strr_dir_sep(const char *path
)
747 char *sep
= strrchr(path
, '/');
749 sep
= strrchr(path
, '\\');
752 return strrchr(path
, '/');
756 /************************************************************************
758 ************************************************************************
759 * Wrapper to the real mkdir, needed only because it doesn't take a
760 * second argument on Win32. Grrr.
761 ***********************************************************************/
762 int hb_mkdir(char * path
)
765 wchar_t path_utf16
[MAX_PATH
];
766 if (!MultiByteToWideChar(CP_UTF8
, 0, path
, -1, path_utf16
, MAX_PATH
))
768 return _wmkdir(path_utf16
);
770 return mkdir(path
, 0755);
774 /************************************************************************
775 * Portable thread implementation
776 ***********************************************************************/
781 thread_func_t
* function
;
787 #if defined( SYS_BEOS )
791 //#elif defined( SYS_CYGWIN )
796 /* Get a unique identifier to thread and represent as 64-bit unsigned.
797 * If unsupported, the value 0 is be returned.
798 * Caller should use result only for display/log purposes.
800 static uint64_t hb_thread_to_integer( const hb_thread_t
* t
)
802 #if defined( USE_PTHREAD )
803 #if defined( SYS_CYGWIN )
804 return (uint64_t)t
->thread
;
805 #elif defined( _WIN32 ) || defined( __MINGW32__ )
806 #if defined(PTW32_STATIC_LIB)
807 return (uint64_t)(ptrdiff_t)t
->thread
.p
;
809 return (uint64_t)t
->thread
;
811 #elif defined( SYS_DARWIN )
812 return (unsigned long)t
->thread
;
814 return (uint64_t)t
->thread
;
821 /************************************************************************
823 ************************************************************************
824 * We use it as the root routine for any thread, for two reasons:
825 * + To set the thread priority on OS X (pthread_setschedparam() could
826 * be called from hb_thread_init(), but it's nicer to do it as we
827 * are sure it is done before the real routine starts)
828 * + Get informed when the thread exits, so we know whether
829 * hb_thread_close() will block or not.
830 ***********************************************************************/
831 static void attribute_align_thread
hb_thread_func( void * _t
)
833 hb_thread_t
* t
= (hb_thread_t
*) _t
;
835 #if defined( SYS_DARWIN ) || defined( SYS_FREEBSD )
836 /* Set the thread priority */
837 struct sched_param param
;
838 memset( ¶m
, 0, sizeof( struct sched_param
) );
839 param
.sched_priority
= t
->priority
;
840 pthread_setschedparam( pthread_self(), SCHED_OTHER
, ¶m
);
843 #if defined( SYS_BEOS )
844 signal( SIGINT
, SIG_IGN
);
847 /* Start the actual routine */
848 t
->function( t
->arg
);
850 /* Inform that the thread can be joined now */
851 hb_deep_log( 2, "thread %"PRIx64
" exited (\"%s\")", hb_thread_to_integer( t
), t
->name
);
854 hb_unlock( t
->lock
);
857 /************************************************************************
859 ************************************************************************
860 * name: user-friendly name
861 * function: the thread routine
862 * arg: argument of the routine
863 * priority: HB_LOW_PRIORITY or HB_NORMAL_PRIORITY
864 ***********************************************************************/
865 hb_thread_t
* hb_thread_init( const char * name
, void (* function
)(void *),
866 void * arg
, int priority
)
868 hb_thread_t
* t
= calloc( sizeof( hb_thread_t
), 1 );
870 t
->name
= strdup( name
);
871 t
->function
= function
;
873 t
->priority
= priority
;
875 t
->lock
= hb_lock_init();
877 /* Create and start the thread */
878 #if defined( SYS_BEOS )
879 t
->thread
= spawn_thread( (thread_func
) hb_thread_func
,
881 resume_thread( t
->thread
);
884 pthread_create( &t
->thread
, NULL
,
885 (void * (*)( void * )) hb_thread_func
, t
);
887 //#elif defined( SYS_CYGWIN )
888 // t->thread = CreateThread( NULL, 0,
889 // (LPTHREAD_START_ROUTINE) hb_thread_func, t, 0, NULL );
891 // /* Maybe use THREAD_PRIORITY_LOWEST instead */
892 // if( priority == HB_LOW_PRIORITY )
893 // SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL );
896 hb_deep_log( 2, "thread %"PRIx64
" started (\"%s\")", hb_thread_to_integer( t
), t
->name
);
900 /************************************************************************
902 ************************************************************************
903 * Joins the thread and frees memory.
904 ***********************************************************************/
905 void hb_thread_close( hb_thread_t
** _t
)
907 hb_thread_t
* t
= *_t
;
909 /* Join the thread */
910 #if defined( SYS_BEOS )
912 wait_for_thread( t
->thread
, &exit_value
);
915 pthread_join( t
->thread
, NULL
);
917 //#elif defined( SYS_CYGWIN )
918 // WaitForSingleObject( t->thread, INFINITE );
921 hb_deep_log( 2, "thread %"PRIx64
" joined (\"%s\")", hb_thread_to_integer( t
), t
->name
);
923 hb_lock_close( &t
->lock
);
929 /************************************************************************
930 * hb_thread_has_exited()
931 ************************************************************************
932 * Returns 1 if the thread can be joined right away, 0 otherwise.
933 ***********************************************************************/
934 int hb_thread_has_exited( hb_thread_t
* t
)
940 hb_unlock( t
->lock
);
945 /************************************************************************
946 * Portable mutex implementation
947 ***********************************************************************/
950 #if defined( SYS_BEOS )
953 pthread_mutex_t mutex
;
954 //#elif defined( SYS_CYGWIN )
959 /************************************************************************
964 ************************************************************************
965 * Basic wrappers to OS-specific semaphore or mutex functions.
966 ***********************************************************************/
967 hb_lock_t
* hb_lock_init()
969 hb_lock_t
* l
= calloc( sizeof( hb_lock_t
), 1 );
971 #if defined( SYS_BEOS )
972 l
->sem
= create_sem( 1, "sem" );
974 pthread_mutexattr_t mta
;
976 pthread_mutexattr_init(&mta
);
978 #if defined( SYS_CYGWIN ) || defined( SYS_FREEBSD )
979 pthread_mutexattr_settype(&mta
, PTHREAD_MUTEX_NORMAL
);
982 pthread_mutex_init( &l
->mutex
, &mta
);
983 //#elif defined( SYS_CYGWIN )
984 // l->mutex = CreateMutex( 0, FALSE, 0 );
990 void hb_lock_close( hb_lock_t
** _l
)
994 #if defined( SYS_BEOS )
995 delete_sem( l
->sem
);
997 pthread_mutex_destroy( &l
->mutex
);
998 //#elif defined( SYS_CYGWIN )
999 // CloseHandle( l->mutex );
1006 void hb_lock( hb_lock_t
* l
)
1008 #if defined( SYS_BEOS )
1009 acquire_sem( l
->sem
);
1011 pthread_mutex_lock( &l
->mutex
);
1012 //#elif defined( SYS_CYGWIN )
1013 // WaitForSingleObject( l->mutex, INFINITE );
1017 void hb_unlock( hb_lock_t
* l
)
1019 #if defined( SYS_BEOS )
1020 release_sem( l
->sem
);
1022 pthread_mutex_unlock( &l
->mutex
);
1023 //#elif defined( SYS_CYGWIN )
1024 // ReleaseMutex( l->mutex );
1028 /************************************************************************
1029 * Portable condition variable implementation
1030 ***********************************************************************/
1033 #if defined( SYS_BEOS )
1036 pthread_cond_t cond
;
1037 //#elif defined( SYS_CYGWIN )
1042 /************************************************************************
1047 ************************************************************************
1048 * Win9x is not supported by this implementation (SignalObjectAndWait()
1049 * only available on Windows 2000/XP).
1050 ***********************************************************************/
1051 hb_cond_t
* hb_cond_init()
1053 hb_cond_t
* c
= calloc( sizeof( hb_cond_t
), 1 );
1058 #if defined( SYS_BEOS )
1061 pthread_cond_init( &c
->cond
, NULL
);
1062 //#elif defined( SYS_CYGWIN )
1063 // c->event = CreateEvent( NULL, FALSE, FALSE, NULL );
1069 void hb_cond_close( hb_cond_t
** _c
)
1071 hb_cond_t
* c
= *_c
;
1073 #if defined( SYS_BEOS )
1075 pthread_cond_destroy( &c
->cond
);
1076 //#elif defined( SYS_CYGWIN )
1077 // CloseHandle( c->event );
1084 void hb_cond_wait( hb_cond_t
* c
, hb_lock_t
* lock
)
1086 #if defined( SYS_BEOS )
1087 c
->thread
= find_thread( NULL
);
1088 release_sem( lock
->sem
);
1089 suspend_thread( c
->thread
);
1090 acquire_sem( lock
->sem
);
1093 pthread_cond_wait( &c
->cond
, &lock
->mutex
);
1094 //#elif defined( SYS_CYGWIN )
1095 // SignalObjectAndWait( lock->mutex, c->event, INFINITE, FALSE );
1096 // WaitForSingleObject( lock->mutex, INFINITE );
1100 void hb_clock_gettime( struct timespec
*tp
)
1104 gettimeofday( &tv
, NULL
);
1105 tp
->tv_sec
= tv
.tv_sec
;
1106 tp
->tv_nsec
= tv
.tv_usec
* 1000;
1114 void hb_cond_timedwait( hb_cond_t
* c
, hb_lock_t
* lock
, int msec
)
1116 #if defined( SYS_BEOS )
1117 c
->thread
= find_thread( NULL
);
1118 release_sem( lock
->sem
);
1119 suspend_thread( c
->thread
);
1120 acquire_sem( lock
->sem
);
1124 hb_clock_gettime(&ts
);
1125 ts
.tv_nsec
+= (msec
% 1000) * 1000000;
1126 ts
.tv_sec
+= msec
/ 1000 + (ts
.tv_nsec
/ 1000000000);
1127 ts
.tv_nsec
%= 1000000000;
1128 pthread_cond_timedwait( &c
->cond
, &lock
->mutex
, &ts
);
1132 void hb_cond_signal( hb_cond_t
* c
)
1134 #if defined( SYS_BEOS )
1135 while( c
->thread
!= -1 )
1138 get_thread_info( c
->thread
, &info
);
1139 if( info
.state
== B_THREAD_SUSPENDED
)
1141 resume_thread( c
->thread
);
1144 /* Looks like we have been called between hb_cond_wait's
1145 release_sem() and suspend_thread() lines. Wait until the
1146 thread is actually suspended before we resume it */
1150 pthread_cond_signal( &c
->cond
);
1151 //#elif defined( SYS_CYGWIN )
1152 // PulseEvent( c->event );
1156 void hb_cond_broadcast( hb_cond_t
* c
)
1159 pthread_cond_broadcast( &c
->cond
);
1163 /************************************************************************
1165 ***********************************************************************/
1172 hb_net_t
* hb_net_open( char * address
, int port
)
1174 hb_net_t
* n
= calloc( sizeof( hb_net_t
), 1 );
1176 struct sockaddr_in sock
;
1177 struct hostent
* host
;
1181 int iResult
, winsock_init
= 0;
1183 // Initialize Winsock
1186 iResult
= WSAStartup(MAKEWORD(2, 2), &wsaData
);
1189 hb_log("WSAStartup failed: %d", iResult
);
1197 /* TODO: find out why this doesn't work on Win32 */
1198 if( !( host
= gethostbyname( address
) ) )
1200 hb_log( "gethostbyname failed (%s)", address
);
1205 memset( &sock
, 0, sizeof( struct sockaddr_in
) );
1206 sock
.sin_family
= host
->h_addrtype
;
1207 sock
.sin_port
= htons( port
);
1208 memcpy( &sock
.sin_addr
, host
->h_addr
, host
->h_length
);
1210 if( ( n
->socket
= socket( host
->h_addrtype
, SOCK_STREAM
, 0 ) ) < 0 )
1212 hb_log( "socket failed" );
1217 if( connect( n
->socket
, (struct sockaddr
*) &sock
,
1218 sizeof( struct sockaddr_in
) ) < 0 )
1220 hb_log( "connect failed" );
1228 int hb_net_send( hb_net_t
* n
, char * buffer
)
1230 return send( n
->socket
, buffer
, strlen( buffer
), 0 );
1233 int hb_net_recv( hb_net_t
* n
, char * buffer
, int size
)
1235 return recv( n
->socket
, buffer
, size
- 1, 0 );
1238 void hb_net_close( hb_net_t
** _n
)
1240 hb_net_t
* n
= (hb_net_t
*) *_n
;
1246 /************************************************************************
1247 * OS Sleep Allow / Prevent
1248 ***********************************************************************/
1251 // 128 chars limit for IOPMAssertionCreateWithName
1252 static CFStringRef reasonForActivity
=
1253 CFSTR("HandBrake is currently scanning and/or encoding");
1256 void* hb_system_sleep_opaque_init()
1258 void *opaque
= NULL
;
1260 opaque
= calloc(sizeof(IOPMAssertionID
), 1);
1263 hb_error("hb_system_sleep: failed to allocate opaque");
1267 IOPMAssertionID
*assertionID
= (IOPMAssertionID
*)opaque
;
1273 void hb_system_sleep_opaque_close(void **opaque
)
1275 if (*opaque
!= NULL
)
1277 hb_system_sleep_private_enable(*opaque
);
1280 if (*opaque
!= NULL
)
1282 IOPMAssertionID
*assertionID
= (IOPMAssertionID
*)*opaque
;
1289 void hb_system_sleep_private_enable(void *opaque
)
1294 hb_error("hb_system_sleep: opaque is NULL");
1297 IOPMAssertionID
*assertionID
= (IOPMAssertionID
*)opaque
;
1298 if (*assertionID
== -1)
1304 IOReturn success
= IOPMAssertionRelease(*assertionID
);
1305 if (success
== kIOReturnSuccess
)
1308 "hb_system_sleep: assertion %d released, sleep allowed",
1314 hb_log("hb_system_sleep: failed to allow system sleep");
1319 void hb_system_sleep_private_disable(void *opaque
)
1324 hb_error("hb_system_sleep: opaque is NULL");
1327 IOPMAssertionID
*assertionID
= (IOPMAssertionID
*)opaque
;
1328 if (*assertionID
!= -1)
1334 IOReturn success
= IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep
,
1335 kIOPMAssertionLevelOn
,
1338 if (success
== kIOReturnSuccess
)
1341 "hb_system_sleep: assertion %d created, sleep prevented",
1346 hb_log("hb_system_sleep: failed to prevent system sleep");