diff --git a/CMakeLists.txt b/CMakeLists.txt index 60c6b76f4a4fa411e28b78cf2ffeb38efdfc9c05..1983d1984d8d716054cb6b110bb3b85ef994bb8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,39 @@ cmake_minimum_required(VERSION 2.8.0) project(acl) #message(${CMAKE_SYSTEM_NAME}) +if( COMMAND CMAKE_POLICY) + message(STATUS "Set CMake Policy") + if(CMAKE_VERSION GREATER "2.8") + CMAKE_POLICY( set CMP0015 OLD ) + CMAKE_POLICY( set CMP0010 OLD ) + CMAKE_POLICY( set CMP0011 OLD ) + endif(CMAKE_VERSION GREATER "2.8") +endif(COMMAND CMAKE_POLICY) + +enable_testing() + +include(CheckCCompilerFlag) +check_c_compiler_flag("-std=c99" COMPILER_SUPPORTS_C99) +check_c_compiler_flag("-std=c89" COMPILER_SUPPORTS_C89) +if(COMPILER_SUPPORTS_C99) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") +elseif(COMPILER_SUPPORTS_C89) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c89") +else() + message(STATUS "The cc compiler ${CMAKE_C_COMPILER} has no C99 or C89 support. Please use a different cc compiler.") +endif() + +include(CheckCXXCompilerFlag) +check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11) +check_cxx_compiler_flag("-std=c++0x" COMPILER_SUPPORTS_CXX0X) +if(COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +elseif(COMPILER_SUPPORTS_CXX0X) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +else() + message(STATUS "The c++ compiler ${CMAKE_CXX_COMPILER} has no C++11 or C++0x support. Please use a different c++ compiler.") +endif() + #set(CMAKE_BUILD_TYPE Release) #set(CMAKE_BUILD_TYPE Release CACHE STRING "set build type to release") @@ -9,9 +42,37 @@ if (${CMAKE_BINARY_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) message(FATAL_ERROR "Please into another dir to build!") endif() -#The below line was built error on Android Studio -#string(TOUPPER ${CMAKE_SYSTEM_NAME} OS_NAME) -if(CMAKE_SYSTEM_NAME MATCHES "Darwin") +#string(TOUPPER ${CMAKE_SYSTEM_NAME} CMAKE_SYSTEM_NAME) +if (CMAKE_SYSTEM_NAME MATCHES "Android") + message(STATUS "current platform: Android") +elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") + message(STATUS "current platform: Linux") +elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") + message(STATUS "current platform: Darwin") + set(CMAKE_MACOSX_RPATH build) +elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + message(STATUS "current platform: FreeBSD") + include_directories( + #/usr/include/c++/4.2 + #/usr/include/c++/4.2/backward + /usr/local/include + /usr/include + ) + + link_directories( + /usr/lib + /usr/local/lib + ) + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--export-dynamic") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,./:./lib:../:../lib") +elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") + message(STATUS "current platform: Windows") +else() + message(FATAL_ERROR "unknown CMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}") +endif() + +if (CMAKE_SYSTEM_NAME MATCHES "Darwin") set(CMAKE_MACOSX_RPATH build) endif() diff --git a/lib_acl/samples/acl/main.c b/lib_acl/samples/acl/main.c index d1f43ee4ee83a9b1424270e38f7a1c5a674870fb..3091d95453bbaaba315277af49fe90b873df4a7c 100644 --- a/lib_acl/samples/acl/main.c +++ b/lib_acl/samples/acl/main.c @@ -8,10 +8,11 @@ int main(void) { printf("current acl version: %s\r\n", acl_version()); printf("ACL_VSTREAM's size: %d\r\n", (int) sizeof(ACL_VSTREAM)); - printf("tid: %lu\r\n", (unsigned long) acl_pthread_self()); printf("main tid: %lu\r\n", acl_main_thread_self()); -#ifdef ACL_FREEBSD +#if defined(__FreeBSD__) && (__FreeBSD__ >= 9) printf("tid: %lu\r\n", (unsigned long) pthread_getthreadid_np()); +#else + printf("tid: %lu\r\n", (unsigned long) acl_pthread_self()); #endif return (0); } diff --git a/lib_acl_cpp/src/stdlib/thread.cpp b/lib_acl_cpp/src/stdlib/thread.cpp index 8db82bfa81bcce047551358ac0b27d4ad2b55a5e..784be95621a6165a08aeda91be5871b6cf0c6da5 100644 --- a/lib_acl_cpp/src/stdlib/thread.cpp +++ b/lib_acl_cpp/src/stdlib/thread.cpp @@ -48,7 +48,11 @@ void* thread::thread_run(void* arg) #ifdef ACL_WINDOWS thr->thread_id_ = GetCurrentThreadId(); #elif defined(ACL_FREEBSD) +#if defined(__FreeBSD__) && (__FreeBSD__ >= 9) thr->thread_id_ = pthread_getthreadid_np(); +#else + thr->thread_id_ = (unsigned long) pthread_self(); +#endif #elif defined(ACL_MACOSX) unsigned long long n; (void) pthread_threadid_np(NULL, &n); @@ -57,9 +61,9 @@ void* thread::thread_run(void* arg) thr->thread_id_ = (unsigned long) pthread_self(); #endif - // 如果线程创建时为分离模式,则当 run 运行时用户有可能 - // 将线程对象销毁了,所以不能再将 thr->return_arg_ 进行 - // 赋值,否则就有可能出现内存非法访问 + // 濡傛灉绾跨▼鍒涘缓鏃朵负鍒嗙妯″紡锛屽垯褰 run 杩愯鏃剁敤鎴锋湁鍙兘 + // 灏嗙嚎绋嬪璞¢攢姣佷簡锛屾墍浠ヤ笉鑳藉啀灏 thr->return_arg_ 杩涜 + // 璧嬪硷紝鍚﹀垯灏辨湁鍙兘鍑虹幇鍐呭瓨闈炴硶璁块棶 if (thr->detachable_) return thr->run(); @@ -72,8 +76,8 @@ bool thread::start() acl_pthread_attr_t attr; acl_pthread_attr_init(&attr); - // 当一个线程对象被重复使用时,为了防止 wait(void** out /* = NULL */) - // 执行时 logger_warn("pthread_josin's arg invalid?") 报错 + // 褰撲竴涓嚎绋嬪璞¤閲嶅浣跨敤鏃讹紝涓轰簡闃叉 wait(void** out /* = NULL */) + // 鎵ц鏃 logger_warn("pthread_josin's arg invalid?") 鎶ラ敊 // --- by 562351190@qq.com thread_id_ = 0; @@ -96,8 +100,8 @@ bool thread::start() return false; } - // 如果线程创建足够快,在 thread_run 中有可能用户将线程对象释放, - // 则下面的代码就会造成内存非法访问 + // 濡傛灉绾跨▼鍒涘缓瓒冲蹇紝鍦 thread_run 涓湁鍙兘鐢ㄦ埛灏嗙嚎绋嬪璞¢噴鏀撅紝 + // 鍒欎笅闈㈢殑浠g爜灏变細閫犳垚鍐呭瓨闈炴硶璁块棶 #if 0 #ifdef ACL_WINDOWS thread_id_ = ((acl_pthread_t*) thread_)->id; @@ -116,7 +120,7 @@ bool thread::wait(void** out /* = NULL */) return false; } - // 尝试等待线程创建成功 + // 灏濊瘯绛夊緟绾跨▼鍒涘缓鎴愬姛 for (int i = 0; i < 10; i++) { if (thread_id_ != 0) @@ -145,7 +149,7 @@ bool thread::wait(void** out /* = NULL */) return false; } - // 比较通过在 thread_run 中截获的参数与 pthread_join 获得的参数是否相同 + // 姣旇緝閫氳繃鍦 thread_run 涓埅鑾风殑鍙傛暟涓 pthread_join 鑾峰緱鐨勫弬鏁版槸鍚︾浉鍚 if (ptr != return_arg_) logger_warn("pthread_josin's arg invalid?"); @@ -156,7 +160,7 @@ bool thread::wait(void** out /* = NULL */) unsigned long thread::thread_id() const { - // 尝试等待线程创建成功 + // 灏濊瘯绛夊緟绾跨▼鍒涘缓鎴愬姛 for (int i = 0; i < 10; i++) { if (thread_id_ != 0) @@ -176,7 +180,11 @@ unsigned long thread::thread_id() const unsigned long thread::thread_self() { #ifdef ACL_FREEBSD +#if defined(__FreeBSD__) && (__FreeBSD__ >= 9) return (unsigned long) pthread_getthreadid_np(); +#else + return (unsigned long) acl_pthread_self(); +#endif #elif defined(ACL_MACOSX) unsigned long long n; (void) pthread_threadid_np(NULL, &n); diff --git a/lib_fiber/c/src/common/pthread_patch.c b/lib_fiber/c/src/common/pthread_patch.c index 88a183ef2c6a46d0de5ded2b3d228f21a6f73460..a019425dc7c548e2a540c9e79ace0af1679de823 100644 --- a/lib_fiber/c/src/common/pthread_patch.c +++ b/lib_fiber/c/src/common/pthread_patch.c @@ -48,7 +48,7 @@ void pthread_end(void) } } -/* 每个进程的唯一初始化函数 */ +/* 姣忎釜杩涚▼鐨勫敮涓鍒濆鍖栧嚱鏁 */ static void pthread_init_once(void) { @@ -79,7 +79,7 @@ static void pthread_init_once(void) __tls_key_list[__tls_value_list_key].key = __tls_value_list_key; } -/* 获得线程局部变量链表 */ +/* 鑾峰緱绾跨▼灞閮ㄥ彉閲忛摼琛 */ static FIFO *tls_value_list_get(void) { @@ -117,17 +117,17 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) return EINVAL; } - /* 只有第一个调用 InterlockedCompareExchange 的线程才会执行 - * init_routine, 后续线程永远在 InterlockedCompareExchange - * 外运行,并且一直进入空循环直至第一个线程执行 init_routine - * 完毕并且将 *once_control 重新赋值, 只有在多核环境中多个线程 - * 同时运行至此时才有可能出现短暂的后续线程空循环现象,如果 - * 多个线程顺序至此,则因为 *once_control 已经被第一个线程重新 - * 赋值而不会进入循环体内只所以如此处理,是为了保证所有线程在 - * 调用 pthread_once 返回前 init_routine 必须被调用且仅能 - * 被调用一次, 但在VC6下,InterlockedCompareExchange 接口定义 - * 有些怪异,需要做硬性指定参数类型,参见 - * Jeffrey Richter, 366 页 + /* 鍙湁绗竴涓皟鐢 InterlockedCompareExchange 鐨勭嚎绋嬫墠浼氭墽琛 + * init_routine, 鍚庣画绾跨▼姘歌繙鍦 InterlockedCompareExchange + * 澶栬繍琛岋紝骞朵笖涓鐩磋繘鍏ョ┖寰幆鐩磋嚦绗竴涓嚎绋嬫墽琛 init_routine + * 瀹屾瘯骞朵笖灏 *once_control 閲嶆柊璧嬪, 鍙湁鍦ㄥ鏍哥幆澧冧腑澶氫釜绾跨▼ + * 鍚屾椂杩愯鑷虫鏃舵墠鏈夊彲鑳藉嚭鐜扮煭鏆傜殑鍚庣画绾跨▼绌哄惊鐜幇璞★紝濡傛灉 + * 澶氫釜绾跨▼椤哄簭鑷虫锛屽垯鍥犱负 *once_control 宸茬粡琚涓涓嚎绋嬮噸鏂 + * 璧嬪艰屼笉浼氳繘鍏ュ惊鐜綋鍐呭彧鎵浠ュ姝ゅ鐞嗭紝鏄负浜嗕繚璇佹墍鏈夌嚎绋嬪湪 + * 璋冪敤 pthread_once 杩斿洖鍓 init_routine 蹇呴』琚皟鐢ㄤ笖浠呰兘 + * 琚皟鐢ㄤ竴娆, 浣嗗湪VC6涓嬶紝InterlockedCompareExchange 鎺ュ彛瀹氫箟 + * 鏈変簺鎬紓锛岄渶瑕佸仛纭ф寚瀹氬弬鏁扮被鍨嬶紝鍙傝 + * Jeffrey Richter, 366 椤 */ while (1) { LONG prev = InterlockedCompareExchange( @@ -135,21 +135,21 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) if (prev == 2) return 0; else if (prev == 0) { - /* 只有第一个线程才会至此 */ + /* 鍙湁绗竴涓嚎绋嬫墠浼氳嚦姝 */ init_routine(); - /* 将 *conce_control 重新赋值以使后续线程不进入 while - * 循环或从 while 循环中跳出 + /* 灏 *conce_control 閲嶆柊璧嬪间互浣垮悗缁嚎绋嬩笉杩涘叆 while + * 寰幆鎴栦粠 while 寰幆涓烦鍑 */ InterlockedExchange(once_control, 2); return 0; } else { assert(prev == 1); - /* 防止空循环过多地浪费CPU */ + /* 闃叉绌哄惊鐜繃澶氬湴娴垂CPU */ Sleep(1); /** sleep 1ms */ } } - return 1; /* 不可达代码,避免编译器报警告 */ + return 1; /* 涓嶅彲杈句唬鐮侊紝閬垮厤缂栬瘧鍣ㄦ姤璀﹀憡 */ } int pthread_key_create(pthread_key_t *key_ptr, void (*destructor)(void*)) @@ -200,7 +200,7 @@ int pthread_setspecific(pthread_key_t key, void *value) if (tls_value->tls_key != NULL && tls_value->tls_key->key == key) { - /* 如果相同的键存在则需要先释放旧数据 */ + /* 濡傛灉鐩稿悓鐨勯敭瀛樺湪鍒欓渶瑕佸厛閲婃斁鏃ф暟鎹 */ if (tls_value->tls_key->destructor && tls_value->value) tls_value->tls_key->destructor(tls_value->value); tls_value->tls_key = NULL; @@ -310,7 +310,11 @@ unsigned long __pthread_self(void) #elif defined(__FreeBSD__) unsigned long __pthread_self(void) { +#if defined(__FreeBSD__) && (__FreeBSD__ >= 9) return (unsigned long) pthread_getthreadid_np(); +#else + return (unsigned long) pthread_self(); +#endif } #else #error "unknown OS"