Browse code

avformat: Add ff_tls_init()/deinit() that initialize OpenSSL

If the application hasn't set up mutex callbacks, we set up
our own using pthreads (or w32pthreads).

Signed-off-by: Martin Storsjö <martin@martin.st>

Martin Storsjö authored on 2011/02/05 07:25:07
Showing 2 changed files
... ...
@@ -19,6 +19,85 @@
19 19
  */
20 20
 
21 21
 #include "network.h"
22
+#include "libavcodec/internal.h"
23
+
24
+#define THREADS (HAVE_PTHREADS || (defined(WIN32) && !defined(__MINGW32CE__)))
25
+
26
+#if THREADS
27
+#if HAVE_PTHREADS
28
+#include <pthread.h>
29
+#else
30
+#include "libavcodec/w32pthreads.h"
31
+#endif
32
+#endif
33
+
34
+#if CONFIG_OPENSSL
35
+#include <openssl/ssl.h>
36
+static int openssl_init;
37
+#if THREADS
38
+#include <openssl/crypto.h>
39
+#include "libavutil/avutil.h"
40
+pthread_mutex_t *openssl_mutexes;
41
+static void openssl_lock(int mode, int type, const char *file, int line)
42
+{
43
+    if (mode & CRYPTO_LOCK)
44
+        pthread_mutex_lock(&openssl_mutexes[type]);
45
+    else
46
+        pthread_mutex_unlock(&openssl_mutexes[type]);
47
+}
48
+#ifndef WIN32
49
+static unsigned long openssl_thread_id(void)
50
+{
51
+    return (intptr_t) pthread_self();
52
+}
53
+#endif
54
+#endif
55
+#endif
56
+
57
+void ff_tls_init(void)
58
+{
59
+    avpriv_lock_avformat();
60
+#if CONFIG_OPENSSL
61
+    if (!openssl_init) {
62
+        SSL_library_init();
63
+        SSL_load_error_strings();
64
+#if THREADS
65
+        if (!CRYPTO_get_locking_callback()) {
66
+            int i;
67
+            openssl_mutexes = av_malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
68
+            for (i = 0; i < CRYPTO_num_locks(); i++)
69
+                pthread_mutex_init(&openssl_mutexes[i], NULL);
70
+            CRYPTO_set_locking_callback(openssl_lock);
71
+#ifndef WIN32
72
+            CRYPTO_set_id_callback(openssl_thread_id);
73
+#endif
74
+        }
75
+#endif
76
+    }
77
+    openssl_init++;
78
+#endif
79
+    avpriv_unlock_avformat();
80
+}
81
+
82
+void ff_tls_deinit(void)
83
+{
84
+    avpriv_lock_avformat();
85
+#if CONFIG_OPENSSL
86
+    openssl_init--;
87
+    if (!openssl_init) {
88
+#if THREADS
89
+        if (CRYPTO_get_locking_callback() == openssl_lock) {
90
+            int i;
91
+            CRYPTO_set_locking_callback(NULL);
92
+            for (i = 0; i < CRYPTO_num_locks(); i++)
93
+                pthread_mutex_destroy(&openssl_mutexes[i]);
94
+            av_free(openssl_mutexes);
95
+        }
96
+#endif
97
+    }
98
+#endif
99
+    avpriv_unlock_avformat();
100
+}
22 101
 
23 102
 int ff_network_init(void)
24 103
 {
... ...
@@ -59,6 +59,9 @@ int ff_socket_nonblock(int socket, int enable);
59 59
 int ff_network_init(void);
60 60
 void ff_network_close(void);
61 61
 
62
+void ff_tls_init(void);
63
+void ff_tls_deinit(void);
64
+
62 65
 int ff_network_wait_fd(int fd, int write);
63 66
 
64 67
 int ff_inet_aton (const char * str, struct in_addr * add);