
#use wml::openssl-macros area=docs page=threads

<title>Documents, threads(3)</title>

<h1>threads(3)</h1>

#use wml::imp::generic

{:
## What's this? [[s|(<STRONG>[^<].+?)</A>(</STRONG><DD>)|$1$2|sg]]
[[s|<P>\s+<P>|<P>|sg]]
[[s|<P>\s+</|</|sg]]
[[s|<DD>\s*<DT>|<DD>&nbsp;<DT>|sg]]
[[s|<DD>\s*</DL>|<DD>&nbsp;</DL>|sg]]
[[s|\[|&#91;|sg]]
[[s|\]|&#93;|sg]]

<!-- INDEX BEGIN -->

<UL>

	<LI><A HREF="#NAME">NAME</A>
	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
	<LI><A HREF="#RETURN_VALUES">RETURN VALUES</A>
	<LI><A HREF="#NOTES">NOTES</A>
	<LI><A HREF="#EXAMPLES">EXAMPLES</A>
	<LI><A HREF="#HISTORY">HISTORY</A>
	<LI><A HREF="#SEE_ALSO">SEE ALSO</A>
</UL>
<!-- INDEX END -->

<HR>
<P>
<HR>
<H1><A NAME="NAME">NAME</A></H1>
<P>
CRYPTO_THREADID_set_callback, CRYPTO_THREADID_get_callback,
CRYPTO_THREADID_current, CRYPTO_THREADID_cmp, CRYPTO_THREADID_cpy,
CRYPTO_THREADID_hash, CRYPTO_set_locking_callback, CRYPTO_num_locks,
CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback,
CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid,
CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support

</P>
<P>
<HR>
<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
<PRE> #include &lt;openssl/crypto.h&gt;
</PRE>
<PRE> /* Don't use this structure directly. */
 typedef struct crypto_threadid_st
         {
         void *ptr;
         unsigned long val;
         } CRYPTO_THREADID;
 /* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
 void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
 void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
 int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
 void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
 void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
 int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a,
                         const CRYPTO_THREADID *b);
 void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest,
                          const CRYPTO_THREADID *src);
 unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
</PRE>
<PRE> int CRYPTO_num_locks(void);
</PRE>
<PRE> /* struct CRYPTO_dynlock_value needs to be defined by the user */
 struct CRYPTO_dynlock_value;
</PRE>
<PRE> void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *
        (*dyn_create_function)(char *file, int line));
 void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)
        (int mode, struct CRYPTO_dynlock_value *l,
        const char *file, int line));
 void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)
        (struct CRYPTO_dynlock_value *l, const char *file, int line));
</PRE>
<PRE> int CRYPTO_get_new_dynlockid(void);
</PRE>
<PRE> void CRYPTO_destroy_dynlockid(int i);
</PRE>
<PRE> void CRYPTO_lock(int mode, int n, const char *file, int line);
</PRE>
<PRE> #define CRYPTO_w_lock(type)    \\
        CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
 \#define CRYPTO_w_unlock(type)  \\
        CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
 \#define CRYPTO_r_lock(type)    \\
        CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
 \#define CRYPTO_r_unlock(type)  \\
        CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
 \#define CRYPTO_add(addr,amount,type)   \\
        CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
</PRE>
<P>
<HR>
<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
<P>
OpenSSL can safely be used in multi-threaded applications provided that at
least two callback functions are set, locking_function and threadid_func.

</P>
<P>
<CODE>locking_function(int</CODE> mode, int n, const char *file, int line)
is needed to perform locking on shared data structures. (Note that OpenSSL
uses a number of global data structures that will be implicitly shared
whenever multiple threads use OpenSSL.) Multi-threaded applications will
crash at random if it is not set.

</P>
<P>
<CODE>locking_function()</CODE> must be able to handle up to
<CODE>CRYPTO_num_locks()</CODE> different mutex locks. It sets the <STRONG>n</STRONG>-th lock if <STRONG>mode</STRONG> &amp;
<STRONG>CRYPTO_LOCK</STRONG>, and releases it otherwise.

</P>
<P>
<STRONG>file</STRONG> and <STRONG>line</STRONG> are the file number of the function setting the lock. They can be useful
for debugging.

</P>
<P>
<CODE>threadid_func(CRYPTO_THREADID</CODE> *id) is needed to record the
currently-executing thread's identifier into <STRONG>id</STRONG>. The implementation of this callback should not fill in <STRONG>id</STRONG> directly, but should use <CODE>CRYPTO_THREADID_set_numeric()</CODE> if
thread IDs are numeric, or <CODE>CRYPTO_THREADID_set_pointer()</CODE> if
they are pointer-based. If the application does not register such a
callback using <CODE>CRYPTO_THREADID_set_callback(),</CODE> then a default
implementation is used - on Windows and BeOS this uses the system's default
thread identifying APIs, and on all other platforms it uses the address of <STRONG>errno</STRONG>. The latter is satisfactory for thread-safety if and only if the platform
has a thread-local error number facility.

</P>
<P>
Once <CODE>threadid_func()</CODE> is registered, or if the built-in default
implementation is to be used;

</P>
<UL>
<LI><STRONG><A NAME="item_CRYPTO_THREADID_current">CRYPTO_THREADID_current() records the currently-executing thread ID into the
given <STRONG>id</STRONG> object.</A></STRONG>
<LI><STRONG><A NAME="item_CRYPTO_THREADID_cmp">CRYPTO_THREADID_cmp() compares two thread IDs (returning zero for equality, ie.
the same semantics as memcmp()).</A></STRONG>
<LI><STRONG><A NAME="item_CRYPTO_THREADID_cpy">CRYPTO_THREADID_cpy() duplicates a thread ID value,</A></STRONG>
<LI><STRONG><A NAME="item_CRYPTO_THREADID_hash">CRYPTO_THREADID_hash() returns a numeric value usable as a hash-table key. This
is usually the exact numeric or pointer-based thread ID used internally, however
this also handles the unusual case where pointers are larger than 'long'
variables and the platform's thread IDs are pointer-based - in this case, mixing
is done to attempt to produce a unique numeric value even though it is not as
wide as the platform's true thread IDs.</A></STRONG>
</UL>
<P>
Additionally, OpenSSL supports dynamic locks, and sometimes, some parts of
OpenSSL need it for better performance. To enable this, the following is
required:

</P>
<UL>
<LI><STRONG><A NAME="item_Three">Three additional callback function, dyn_create_function, dyn_lock_function
and dyn_destroy_function.</A></STRONG>
<LI><STRONG><A NAME="item_A">A structure defined with the data that each lock needs to handle.</A></STRONG>
</UL>
<P>
struct CRYPTO_dynlock_value has to be defined to contain whatever structure
is needed to handle locks.

</P>
<P>
<CODE>dyn_create_function(const</CODE> char *file, int line) is needed to
create a lock. Multi-threaded applications might crash at random if it is
not set.

</P>
<P>
<CODE>dyn_lock_function(int</CODE> mode, CRYPTO_dynlock *l, const char
*file, int line) is needed to perform locking off dynamic lock numbered n.
Multi-threaded applications might crash at random if it is not set.

</P>
<P>
<CODE>dyn_destroy_function(CRYPTO_dynlock</CODE> *l, const char *file, int
line) is needed to destroy the lock l. Multi-threaded applications might
crash at random if it is not set.

</P>
<P>
<CODE>CRYPTO_get_new_dynlockid()</CODE> is used to create locks. It will
call dyn_create_function for the actual creation.

</P>
<P>
<CODE>CRYPTO_destroy_dynlockid()</CODE> is used to destroy locks. It will
call dyn_destroy_function for the actual destruction.

</P>
<P>
<CODE>CRYPTO_lock()</CODE> is used to lock and unlock the locks. mode is a
bitfield describing what should be done with the lock. n is the number of
the lock as returned from <CODE>CRYPTO_get_new_dynlockid().</CODE> mode can
be combined from the following values. These values are pairwise exclusive,
with undefined behaviour if misused (for example, CRYPTO_READ and
CRYPTO_WRITE should not be used together):

</P>
<PRE>        CRYPTO_LOCK     0x01
        CRYPTO_UNLOCK   0x02
        CRYPTO_READ     0x04
        CRYPTO_WRITE    0x08
</PRE>
<P>
<HR>
<H1><A NAME="RETURN_VALUES">RETURN VALUES</A></H1>
<P>
<CODE>CRYPTO_num_locks()</CODE> returns the required number of locks.

</P>
<P>
<CODE>CRYPTO_get_new_dynlockid()</CODE> returns the index to the newly
created lock.

</P>
<P>
The other functions return no values.

</P>
<P>
<HR>
<H1><A NAME="NOTES">NOTES</A></H1>
<P>
You can find out if OpenSSL was configured with thread support:

</P>
<PRE> #define OPENSSL_THREAD_DEFINES
 \#include &lt;openssl/opensslconf.h&gt;
 \#if defined(OPENSSL_THREADS)
   // thread support enabled
 \#else
   // no thread support
 \#endif
</PRE>
<P>
Also, dynamic locks are currently not used internally by OpenSSL, but may
do so in the future.

</P>
<P>
<HR>
<H1><A NAME="EXAMPLES">EXAMPLES</A></H1>
<P>
<STRONG>crypto/threads/mttest.c</STRONG> shows examples of the callback functions on Solaris, Irix and Win32.

</P>
<P>
<HR>
<H1><A NAME="HISTORY">HISTORY</A></H1>
<P>
<CODE>CRYPTO_set_locking_callback()</CODE> is available in all versions of
SSLeay and OpenSSL. <CODE>CRYPTO_num_locks()</CODE> was added in OpenSSL
0.9.4. All functions dealing with dynamic locks were added in OpenSSL
0.9.5b-dev.
<STRONG>CRYPTO_THREADID</STRONG> and associated functions were introduced in OpenSSL 1.0.0 to replace
(actually, deprecate) the previous <CODE>CRYPTO_set_id_callback(),</CODE>
<CODE>CRYPTO_get_id_callback(),</CODE> and <CODE>CRYPTO_thread_id()</CODE>
functions which assumed thread IDs to always be represented by 'unsigned
long'.

</P>
<P>
<HR>
<H1><A NAME="SEE_ALSO">SEE ALSO</A></H1>
<P>
<A HREF="../crypto/crypto.html#">crypto(3)</A>



</P>
:}


