Openssl : thread safety
来源:互联网 发布:微信分销系统源码 编辑:程序博客网 时间:2024/06/05 18:16
https://www.openssl.org/docs/man1.0.2/crypto/threads.html
OpenSSL can safely be used in multi-threaded applications provided that at least two callback functions are set, locking_function and threadid_func.
根据官方文档,为了让OpsnSSL是线程安全的,需要至少提供两个 callback function:
- locking_function
- threadid_func
locking_function
locking_function(int mode, int n, const char *file, int line) is needed to perform locking on shared data structures. (Note that OpenSSL uses a number of global data structures that will be implicitly shared whenever multiple threads use OpenSSL.) Multi-threaded applications will crash at random if it is not set.
locking_function() must be able to handle up to CRYPTO_num_locks() different mutex locks. It sets the n-th lock if mode & CRYPTO_LOCK, and releases it otherwise.
file and line are the file number of the function setting the lock. They can be useful for debugging.
locking_function(int mode, int n, const char *file, int line)
需要对共享的数据结构进行加锁。(OpenSSL使用一些全局的数据结构,因此在多线程环境下会有问题。)如果没有设置此callback function,那么多线程OpenSLL程序会随机意外的crash。(如果没有设置此回调函数,你的程序也没crash,不要认为这么做没有问题,只是crash还没有发生而已)
locking_function
必须能够处理最多CRYPTO_num_locks()
个不同的mutex锁,如果 mode & CRYPTO_LOCK
为true, 它会lock 第n个锁;否则unlock。
参数flie和line用于debug。
threadid_func
threadid_func(CRYPTO_THREADID *id) is needed to record the currently-executing thread’s identifier into id. The implementation of this callback should not fill in id directly, but should use CRYPTO_THREADID_set_numeric() if thread IDs are numeric, or CRYPTO_THREADID_set_pointer() if they are pointer-based. If the application does not register such a callback using CRYPTO_THREADID_set_callback(), then a default implementation is used - on Windows and BeOS this uses the system’s default thread identifying APIs, and on all other platforms it uses the address of errno. The latter is satisfactory for thread-safety if and only if the platform has a thread-local error number facility.
threadid_func(CRYPTO_THREADID *id)
需要将当前执行线程的identifier记录到id
中。
一个完整的例子
https://github.com/openssl/openssl/blob/OpenSSL_1_0_2g/crypto/threads/th-lock.c
上面是OpenSSL 1.0.2g版本中的代码,已经封装好了两个函数:
void CRYPTO_thread_setup(void); // 注册回调void CRYPTO_thread_cleanup(void); // 执行清理工作
关键代码:
static pthread_mutex_t *lock_cs;static long *lock_count;void CRYPTO_thread_setup(void){ int i; lock_cs = (pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); lock_count = (long *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); if (!lock_cs || !lock_count) { /* Nothing we can do about this...void function! */ if (lock_cs) OPENSSL_free(lock_cs); if (lock_count) OPENSSL_free(lock_count); return; } for (i = 0; i < CRYPTO_num_locks(); i++) { lock_count[i] = 0; pthread_mutex_init(&(lock_cs[i]), NULL); } CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); CRYPTO_set_locking_callback((void (*)(int, int, const char*, int))pthreads_locking_callback);}void thread_cleanup(void){ int i; CRYPTO_set_locking_callback(NULL); for (i = 0; i < CRYPTO_num_locks(); i++) { pthread_mutex_destroy(&(lock_cs[i])); } OPENSSL_free(lock_cs); OPENSSL_free(lock_count);}void pthreads_locking_callback(int mode, int type, char *file, int line){# if 0 fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n", CRYPTO_thread_id(), (mode & CRYPTO_LOCK) ? "l" : "u", (type & CRYPTO_READ) ? "r" : "w", file, line);# endif# if 0 if (CRYPTO_LOCK_SSL_CERT == type) fprintf(stderr, "(t,m,f,l) %ld %d %s %d\n", CRYPTO_thread_id(), mode, file, line);# endif if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&(lock_cs[type])); lock_count[type]++; } else { pthread_mutex_unlock(&(lock_cs[type])); }}unsigned long pthreads_thread_id(void){ unsigned long ret; ret = (unsigned long)pthread_self(); return (ret);}
- Openssl : thread safety
- Thread safety
- Thread Safety
- TraceSource Thread-safety
- boost::shared_ptr Thread Safety
- Thread safety & Re-entrancy
- Chapter 2. Thread Safety
- Thread Safety of shared_ptr
- reentrant thread safety
- JCIP-2-Thread Safety
- Reentrancy and Thread-Safety
- Thread Safety Summary
- Lecture 20: Thread Safety
- Thread Safety Analysis
- Thread-safety and POSIX.1
- Thread Safety and Shared Resources
- Thread safety of google/dense_hash_map
- Thread Safety Using the Volatile Keyword
- 基于事件的 JavaScript 编程:异步与同步
- Apt-get update出错
- Cocos Creator v1.5.0 内测版发布帖(5月5日更新 beta.3)
- Oracle 12C 新特性之级联truncate
- ABAP 简单的ALV使用经验
- Openssl : thread safety
- java.io.IOException: Server returned HTTP response code: 415 for URL:xxxxxx
- [leetcode: Python]225. Implement Stack using Queues
- 526. Beautiful Arrangement
- 数据库优化操作及方案
- 河南第十届ACM省赛-C-最小密钥
- 设计模式:接口适配(适配器,桥接,外观)
- 关于JavaScript中的方法是否加括号的问题
- 洛谷P1000 超级玛丽游戏