aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure.in12
-rw-r--r--xbmc/utils/CryptThreading.cpp124
-rw-r--r--xbmc/utils/CryptThreading.h41
-rw-r--r--xbmc/utils/Makefile1
4 files changed, 178 insertions, 0 deletions
diff --git a/configure.in b/configure.in
index 83840a8f9a..95661a54f1 100755
--- a/configure.in
+++ b/configure.in
@@ -698,6 +698,18 @@ AC_CHECK_HEADER([vorbis/vorbisenc.h],, AC_MSG_ERROR($missing_library))
AC_CHECK_HEADER([libmodplug/modplug.h],, AC_MSG_ERROR($missing_library))
AC_CHECK_HEADER([curl/curl.h],, AC_MSG_ERROR($missing_library))
AC_CHECK_HEADER([FLAC/stream_decoder.h],, AC_MSG_ERROR($missing_library))
+
+# we need to check for the header because if it exists we set the openssl
+# and gcrypt MT callback hooks. This is mostly so that libcurl operates
+# in MT manner correctly.
+AC_CHECK_HEADER([openssl/crypto.h], AC_DEFINE([HAVE_OPENSSL],[1],[Define if we have openssl]),)
+AC_CHECK_HEADER([gcrypt.h], gcrypt_headers_available=yes,gcrypt_headers_available=no)
+if test "$gcrypt_headers_available" = "yes"; then
+ # if we have the headers then we must have the lib
+ AC_CHECK_LIB([gcrypt],[gcry_control],, AC_MSG_ERROR($missing_library))
+ AC_DEFINE([HAVE_GCRYPT],[1],[Define if we have gcrypt])
+fi
+
AC_CHECK_LIB([bz2], [main],, AC_MSG_ERROR($missing_library))
AC_CHECK_LIB([jpeg], [main],, AC_MSG_ERROR($missing_library)) # check for cximage
AC_CHECK_LIB([tiff], [main],, AC_MSG_ERROR($missing_library))
diff --git a/xbmc/utils/CryptThreading.cpp b/xbmc/utils/CryptThreading.cpp
new file mode 100644
index 0000000000..5bc251ac51
--- /dev/null
+++ b/xbmc/utils/CryptThreading.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2005-2008 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifdef TARGET_WINDOWS
+#error "The threading options for the cryptography libraries don't need to be and shouldn't be set on Windows. Do not include CryptThreading in your windows project."
+#endif
+
+#include "CryptThreading.h"
+#include "threads/Thread.h"
+#include "utils/log.h"
+
+#if (defined HAVE_CONFIG_H) && (!defined WIN32)
+ #include "config.h"
+#else
+#define HAVE_OPENSSL
+#endif
+
+#ifdef HAVE_OPENSSL
+#include <openssl/crypto.h>
+#endif
+
+#ifdef HAVE_GCRYPT
+#include <gcrypt.h>
+#include <errno.h>
+
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+#endif
+
+/* ========================================================================= */
+/* openssl locking implementation for curl */
+static CCriticalSection* getlock(int index)
+{
+ return g_cryptThreadingInitializer.get_lock(index);
+}
+
+static void lock_callback(int mode, int type, const char* file, int line)
+{
+ if (mode & 0x01 /* CRYPTO_LOCK from openssl/crypto.h */ )
+ getlock(type)->lock();
+ else
+ getlock(type)->unlock();
+}
+
+static unsigned long thread_id()
+{
+ return (unsigned long)CThread::GetCurrentThreadId();
+}
+/* ========================================================================= */
+
+CryptThreadingInitializer::CryptThreadingInitializer()
+{
+ bool attemptedToSetSSLMTHook = false;
+#ifdef HAVE_OPENSSL
+ // set up OpenSSL
+ numlocks = CRYPTO_num_locks();
+ CRYPTO_set_id_callback(thread_id);
+ CRYPTO_set_locking_callback(lock_callback);
+ attemptedToSetSSLMTHook = true;
+#else
+ numlocks = 1;
+#endif
+
+ locks = new CCriticalSection*[numlocks];
+ for (int i = 0; i < numlocks; i++)
+ locks[i] = NULL;
+
+#ifdef HAVE_GCRYPT
+ // set up gcrypt
+ gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+ attemptedToSetSSLMTHook = true;
+#endif
+
+ if (!attemptedToSetSSLMTHook)
+ CLog::Log(LOGWARNING, "Could not determine the libcurl security library to set the locking scheme. This may cause problem with multithreaded use of ssl or libraries that depend on it (libcurl).");
+
+}
+
+CryptThreadingInitializer::~CryptThreadingInitializer()
+{
+ CSingleLock l(locksLock);
+#ifdef HAVE_OPENSSL
+ CRYPTO_set_locking_callback(NULL);
+#endif
+
+ for (int i = 0; i < numlocks; i++)
+ delete locks[i]; // I always forget ... delete is NULL safe.
+
+ delete [] locks;
+}
+
+CCriticalSection* CryptThreadingInitializer::get_lock(int index)
+{
+ CSingleLock l(locksLock);
+ CCriticalSection* curlock = locks[index];
+ if (curlock == NULL)
+ {
+ curlock = new CCriticalSection();
+ locks[index] = curlock;
+ }
+
+ return curlock;
+}
+
+
+
+
diff --git a/xbmc/utils/CryptThreading.h b/xbmc/utils/CryptThreading.h
new file mode 100644
index 0000000000..e33984b94b
--- /dev/null
+++ b/xbmc/utils/CryptThreading.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2005-2008 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#pragma once
+
+#include "utils/GlobalsHandling.h"
+#include "threads/CriticalSection.h"
+
+class CryptThreadingInitializer
+{
+ CCriticalSection** locks;
+ int numlocks;
+ CCriticalSection locksLock;
+
+public:
+ CryptThreadingInitializer();
+ ~CryptThreadingInitializer();
+
+ CCriticalSection* get_lock(int index);
+};
+
+XBMC_GLOBAL_REF(CryptThreadingInitializer,g_cryptThreadingInitializer);
+#define g_cryptThreadingInitializer XBMC_GLOBAL_USE(CryptThreadingInitializer)
diff --git a/xbmc/utils/Makefile b/xbmc/utils/Makefile
index c91572ec32..a420c5b163 100644
--- a/xbmc/utils/Makefile
+++ b/xbmc/utils/Makefile
@@ -7,6 +7,7 @@ SRCS=AlarmClock.cpp \
CharsetConverter.cpp \
CPUInfo.cpp \
Crc32.cpp \
+ CryptThreading.cpp \
DownloadQueue.cpp \
DownloadQueueManager.cpp \
Fanart.cpp \