7101N/A# This file adds the code to setup internal mutexes and callback function.
7101N/A# This change was implemented in-house. The issue was brought up to
7101N/A# the upstream engineers, but there was no commitment.
7101N/A #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
7101N/A static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */
7101N/A static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
+static pthread_mutex_t *solaris_openssl_locks;
static void (MS_FAR *locking_callback) (int mode, int type,
const char *file, int line) = 0;
static int (MS_FAR *add_lock_callback) (int *pointer, int amount,
void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
(const char *file, int line))
- dynlock_create_callback = func;
+ * we now setup our own dynamic locking callback, and disallow
+ * setting of another locking callback.
void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode,
- dynlock_lock_callback = func;
+ * we now setup our own dynamic locking callback, and disallow
+ * setting of another locking callback.
void CRYPTO_set_dynlock_destroy_callback(void (*func)
(struct CRYPTO_dynlock_value *l,
const char *file, int line))
- dynlock_destroy_callback = func;
+ * we now setup our own dynamic locking callback, and disallow
+ * setting of another locking callback.
void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
return (add_lock_callback);
+ * This is the locking callback function which all applications will be
+ * using when CRYPTO_lock() is called.
+static void solaris_locking_callback(int mode, int type, const char *file,
+ if (mode & CRYPTO_LOCK) {
+ pthread_mutex_lock(&solaris_openssl_locks[type]);
+ pthread_mutex_unlock(&solaris_openssl_locks[type]);
+ * Implement Solaris's own dynamic locking routines.
+static struct CRYPTO_dynlock_value *
+solaris_dynlock_create(const char *file, int line)
+ pthread_mutex_t *dynlock;
+ dynlock = OPENSSL_malloc(sizeof(pthread_mutex_t));
+ ret = pthread_mutex_init(dynlock, NULL);
+ return ((struct CRYPTO_dynlock_value *)dynlock);
+solaris_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock,
+ const char *file, int line)
+ if (mode & CRYPTO_LOCK) {
+ ret = pthread_mutex_lock((pthread_mutex_t *)dynlock);
+ ret = pthread_mutex_unlock((pthread_mutex_t *)dynlock);
+ OPENSSL_assert(ret == 0);
+solaris_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock,
+ const char *file, int line)
+ ret = pthread_mutex_destroy((pthread_mutex_t *)dynlock);
+ * This function is called when a child process is forked to setup its own
+ * global locking callback function ptr and mutexes.
+static void solaris_fork_child(void)
+ * clear locking_callback to indicate that locks should
+ locking_callback = NULL;
+ solaris_locking_setup();
+ * This function allocates and initializes the global mutex array, and
+ * sets the locking callback.
+void solaris_locking_setup()
+ /* setup the dynlock callback if not already */
+ if (dynlock_create_callback == NULL) {
+ dynlock_create_callback = solaris_dynlock_create;
+ if (dynlock_lock_callback == NULL) {
+ dynlock_lock_callback = solaris_dynlock_lock;
+ if (dynlock_destroy_callback == NULL) {
+ dynlock_destroy_callback = solaris_dynlock_destroy;
+ /* locking callback is already setup. Nothing to do */
+ if (locking_callback != NULL) {
+ * Set atfork handler so that child can setup its own mutexes and
+ * locking callbacks when it is forked
+ (void) pthread_atfork(NULL, NULL, solaris_fork_child);
+ /* allocate locks needed by OpenSSL */
+ num_locks = CRYPTO_num_locks();
+ solaris_openssl_locks =
+ OPENSSL_malloc(sizeof (pthread_mutex_t) * num_locks);
+ if (solaris_openssl_locks == NULL) {
+ "solaris_locking_setup: memory allocation failure.\n");
+ /* initialize openssl mutexes */
+ for (i = 0; i < num_locks; i++) {
+ pthread_mutex_init(&solaris_openssl_locks[i], NULL);
+ locking_callback = solaris_locking_callback;
void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
const char *file, int line))
- locking_callback = func;
+ * we now setup our own locking callback and mutexes, and disallow
+ * setting of another locking callback.
void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
- threadid_callback = func;
+ * Use the backup method (the address of 'errno') to identify the
+ * thread and disallow setting the threadid callback.
void CRYPTO_set_id_callback(unsigned long (*func) (void))
+ * Setting the id callback is disallowed.
unsigned long CRYPTO_thread_id(void)
void *OPENSSL_stderr(void);
extern int OPENSSL_NONPIC_relocated;
+void solaris_locking_setup();
.size OPENSSL_cleanse,.-OPENSSL_cleanse
.section ".init",#alloc,#execinstr
+ call solaris_locking_setup
.extern OPENSSL_cpuid_setup
.hidden OPENSSL_cpuid_setup
+.extern solaris_locking_setup
+.hidden solaris_locking_setup
+ call solaris_locking_setup
.hidden OPENSSL_ia32cap_P
&function_end_B("OPENSSL_ia32_rdrand");
+&initseg("solaris_locking_setup");
&initseg("OPENSSL_cpuid_setup");