Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Example of OpenSSL Multithreading

2,207 views
Skip to first unread message

Ashada Karunaratna

unread,
Aug 27, 2001, 8:43:21 AM8/27/01
to
Hi All,

Is there anyone who has an example of SSL Multithreading in Linux
platform.
I saw the example shipped with OpenSSL. But it seem to be bit unclear
for me. If anyone have an example on Multithreading please send me.


Ashada
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org

Jim McLaughlin

unread,
Aug 27, 2001, 11:31:06 AM8/27/01
to
This is a multi-part message in MIME format.
--------------F3811CD3D961C2584B6E310E
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,
I yanked these from the examples and put them in their own file. Call
SSL_Thread_setup before you spawn, and SSL_thread_cleanup when the
program terminates.
--
Jim McLaughlin
Software Engineer
Stonewater Software

Phone: 847-864-1060 x107
Fax : 847-864-1238
email: j...@stonewatersoftware.com
--------------F3811CD3D961C2584B6E310E
Content-Type: text/plain; charset=us-ascii;
name="SSL_Thread_Init.h"
Content-Disposition: inline;
filename="SSL_Thread_Init.h"
Content-Transfer-Encoding: 7bit

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
//#include <typedefs.h>
#include <openssl/e_os.h>
#include <pthread.h>
#include <openssl/lhash.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>

static pthread_mutex_t *lock_cs;
static long *lock_count;

#ifdef __cplusplus
extern "C" {
#endif
void SSL_thread_setup(void);
void SSL_thread_cleanup(void);
void SSL_pthreads_locking_callback(int mode, int type, char *file, int line);
unsigned long SSL_pthreads_thread_id(void);
#ifdef __cplusplus
}
#endif

--------------F3811CD3D961C2584B6E310E
Content-Type: text/plain; charset=us-ascii;
name="SSL_Thread_Init.c"
Content-Disposition: inline;
filename="SSL_Thread_Init.c"
Content-Transfer-Encoding: 7bit

#include "SSL_Thread_Init.h"


void SSL_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));
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 (*)())SSL_pthreads_thread_id);
CRYPTO_set_locking_callback((void (*)())SSL_pthreads_locking_callback);
}

void SSL_thread_cleanup(void) {
int i;

CRYPTO_set_locking_callback(NULL);
fprintf(stderr,"cleanup\n");
for (i=0; i<CRYPTO_num_locks(); i++) {
pthread_mutex_destroy(&(lock_cs[i]));
fprintf(stderr,"%8ld:%s\n",lock_count[i], CRYPTO_get_lock_name(i));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);

fprintf(stderr,"done cleanup\n");
}

void SSL_pthreads_locking_callback(int mode, int type, char *file, int line) {
#ifdef undef
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 (CRYPTO_LOCK_SSL_CERT == type)
fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
CRYPTO_thread_id(),
mode,file,line);
*/
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&(lock_cs[type]));
lock_count[type]++;
} else {
pthread_mutex_unlock(&(lock_cs[type]));
}
}

unsigned long SSL_pthreads_thread_id(void) {
unsigned long ret;
ret=(unsigned long)pthread_self();
return(ret);
}


--------------F3811CD3D961C2584B6E310E--

Dima Volodin

unread,
Aug 27, 2001, 1:19:56 PM8/27/01
to
On Mon, 27 Aug 2001 10:27:28 -0500, Jim McLaughlin wrote:

[...]


unsigned long SSL_pthreads_thread_id(void) {
unsigned long ret;
ret=(unsigned long)pthread_self();
return(ret);
}

[...]

The return type of pthread_self(), pthread_t, is not necessary a type
castable to unsigned long, which makes this piece somewhat non-portable.


Dima

Jim McLaughlin

unread,
Aug 27, 2001, 2:02:54 PM8/27/01
to

Unfortunately, the function signature requires it:
void CRYPTO_set_id_callback(unsigned long (*id_function)(void));


--
Jim McLaughlin
Software Engineer
Stonewater Software

Rich Salz

unread,
Aug 27, 2001, 3:02:05 PM8/27/01
to
This is a multi-part message in MIME format.
--------------4A8CA4C0BAA069CA4BA0C1CE

Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

> > unsigned long SSL_pthreads_thread_id(void) {


> > unsigned long ret;
> > ret=(unsigned long)pthread_self();
> > return(ret);
> > }

> > The return type of pthread_self(), pthread_t, is not necessary a type


> > castable to unsigned long, which makes this piece somewhat non-portable.
>

> Unfortunately, the function signature requires it:
> void CRYPTO_set_id_callback(unsigned long (*id_function)(void));

Yes, this is a pain. On those places where pthread_t is a scalar type,
it will work; on places where it's a struct, it will probably fail to
compile. You can work around that by doing
pthread_t me = pthread_self()
unsigned long ret;
memcpy(&ret, &me, sizeof ret)
return ret
But that's probably getting valid, but wrong and buggy :), code.

The attached code compiles, and should work portably. Something like it
should be used as a replacement for pthreads_thread_id that is currently
in crypto/threads/th-lock.c and for the code snippet above.

Hope this helps.
/r$

--
Zolera Systems, Your Key to Online Integrity
Securing Web services: XML, SOAP, Dig-sig, Encryption
http://www.zolera.com
--------------4A8CA4C0BAA069CA4BA0C1CE
Content-Type: text/plain; charset=us-ascii;
name="key.c"
Content-Disposition: inline;
filename="key.c"
Content-Transfer-Encoding: 7bit

/*
** Sample code, showing how to use POSIX threads's TSD to hold a
** small unique id value. Except for perhaps the header files, this
** should be highly portable code. (Famous last words.)
** This code is in the public domain, 27 Aug 2001.
** Rich Salz
** Zolera Systems, Your Key to Online Integrity
** Securing Web services: XML, SOAP, Dig-sig, Encryption
** http://www.zolera.com
*/
#include <pthread.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

/* tid_once ensures the following are only initialized once. */
static pthread_once_t tid_once = PTHREAD_ONCE_INIT;

/* The key for storing our thread-specific data. */
static pthread_key_t tid_key;

/* The mutex that protects our global counter. */
static pthread_mutex_t tid_mutex;

/* Our local thread id. Also a hint that we're not initialized. */
static unsigned long tid = 0;


/*
** Initialization function. Create the TSD key, the mutex, and clear
** the counter.
*/
static void
init_openssl_tid(void)
{
int st;

st = pthread_key_create(&tid_key, NULL);
assert(st >= 0);
st = pthread_mutex_init(&tid_mutex, NULL);
assert(st >= 0);
tid = 0;
}


/*
** Return a unique ID for every thread. Imposes no overhead if never
** called.
*/
unsigned long SSL_pthreads_thread_id(void)
{
int st;
unsigned long* ulp;
void* vp;

/* Initialize if necessary. */
if (tid == 0)
pthread_once(&tid_once, init_openssl_tid);

/* Already know our ID? */
vp = pthread_getspecific(tid_key);
if (vp)
ulp = (unsigned long*)vp;
else {
/* No; lock and bump. */
ulp = (unsigned long*)malloc(sizeof *ulp);
st = pthread_mutex_lock(&tid_mutex);
assert(st >= 0);
*ulp = ++tid;
st = pthread_mutex_unlock(&tid_mutex);
assert(st >= 0);
pthread_setspecific(tid_key, ulp);
}

return *ulp;
}

--------------4A8CA4C0BAA069CA4BA0C1CE--

0 new messages