• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavformat/network.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2007 The Libav Project
00003  *
00004  * This file is part of Libav.
00005  *
00006  * Libav is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * Libav is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with Libav; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include "network.h"
00022 #include "libavcodec/internal.h"
00023 
00024 #define THREADS (HAVE_PTHREADS || (defined(WIN32) && !defined(__MINGW32CE__)))
00025 
00026 #if THREADS
00027 #if HAVE_PTHREADS
00028 #include <pthread.h>
00029 #else
00030 #include "libavcodec/w32pthreads.h"
00031 #endif
00032 #endif
00033 
00034 #if CONFIG_OPENSSL
00035 #include <openssl/ssl.h>
00036 static int openssl_init;
00037 #if THREADS
00038 #include <openssl/crypto.h>
00039 #include "libavutil/avutil.h"
00040 pthread_mutex_t *openssl_mutexes;
00041 static void openssl_lock(int mode, int type, const char *file, int line)
00042 {
00043     if (mode & CRYPTO_LOCK)
00044         pthread_mutex_lock(&openssl_mutexes[type]);
00045     else
00046         pthread_mutex_unlock(&openssl_mutexes[type]);
00047 }
00048 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
00049 static unsigned long openssl_thread_id(void)
00050 {
00051     return (intptr_t) pthread_self();
00052 }
00053 #endif
00054 #endif
00055 #endif
00056 #if CONFIG_GNUTLS
00057 #include <gnutls/gnutls.h>
00058 #if THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00
00059 #include <gcrypt.h>
00060 #include <errno.h>
00061 #undef malloc
00062 #undef free
00063 GCRY_THREAD_OPTION_PTHREAD_IMPL;
00064 #endif
00065 #endif
00066 
00067 void ff_tls_init(void)
00068 {
00069     avpriv_lock_avformat();
00070 #if CONFIG_OPENSSL
00071     if (!openssl_init) {
00072         SSL_library_init();
00073         SSL_load_error_strings();
00074 #if THREADS
00075         if (!CRYPTO_get_locking_callback()) {
00076             int i;
00077             openssl_mutexes = av_malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
00078             for (i = 0; i < CRYPTO_num_locks(); i++)
00079                 pthread_mutex_init(&openssl_mutexes[i], NULL);
00080             CRYPTO_set_locking_callback(openssl_lock);
00081 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
00082             CRYPTO_set_id_callback(openssl_thread_id);
00083 #endif
00084         }
00085 #endif
00086     }
00087     openssl_init++;
00088 #endif
00089 #if CONFIG_GNUTLS
00090 #if THREADS && GNUTLS_VERSION_NUMBER < 0x020b00
00091     if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
00092         gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
00093 #endif
00094     gnutls_global_init();
00095 #endif
00096     avpriv_unlock_avformat();
00097 }
00098 
00099 void ff_tls_deinit(void)
00100 {
00101     avpriv_lock_avformat();
00102 #if CONFIG_OPENSSL
00103     openssl_init--;
00104     if (!openssl_init) {
00105 #if THREADS
00106         if (CRYPTO_get_locking_callback() == openssl_lock) {
00107             int i;
00108             CRYPTO_set_locking_callback(NULL);
00109             for (i = 0; i < CRYPTO_num_locks(); i++)
00110                 pthread_mutex_destroy(&openssl_mutexes[i]);
00111             av_free(openssl_mutexes);
00112         }
00113 #endif
00114     }
00115 #endif
00116 #if CONFIG_GNUTLS
00117     gnutls_global_deinit();
00118 #endif
00119     avpriv_unlock_avformat();
00120 }
00121 
00122 int ff_network_inited_globally;
00123 
00124 int ff_network_init(void)
00125 {
00126 #if HAVE_WINSOCK2_H
00127     WSADATA wsaData;
00128 #endif
00129 
00130     if (!ff_network_inited_globally)
00131         av_log(NULL, AV_LOG_WARNING, "Using network protocols without global "
00132                                      "network initialization. Please use "
00133                                      "avformat_network_init(), this will "
00134                                      "become mandatory later.\n");
00135 #if HAVE_WINSOCK2_H
00136     if (WSAStartup(MAKEWORD(1,1), &wsaData))
00137         return 0;
00138 #endif
00139     return 1;
00140 }
00141 
00142 int ff_network_wait_fd(int fd, int write)
00143 {
00144     int ev = write ? POLLOUT : POLLIN;
00145     struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
00146     int ret;
00147     ret = poll(&p, 1, 100);
00148     return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
00149 }
00150 
00151 void ff_network_close(void)
00152 {
00153 #if HAVE_WINSOCK2_H
00154     WSACleanup();
00155 #endif
00156 }
00157 
00158 #if HAVE_WINSOCK2_H
00159 int ff_neterrno(void)
00160 {
00161     int err = WSAGetLastError();
00162     switch (err) {
00163     case WSAEWOULDBLOCK:
00164         return AVERROR(EAGAIN);
00165     case WSAEINTR:
00166         return AVERROR(EINTR);
00167     }
00168     return -err;
00169 }
00170 #endif
00171 
00172 int ff_is_multicast_address(struct sockaddr *addr)
00173 {
00174     if (addr->sa_family == AF_INET) {
00175         return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr));
00176     }
00177 #if HAVE_STRUCT_SOCKADDR_IN6
00178     if (addr->sa_family == AF_INET6) {
00179         return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr);
00180     }
00181 #endif
00182 
00183     return 0;
00184 }
00185 
Generated on Sat Mar 17 2012 12:57:54 for Libav by doxygen 1.7.1