thread_safety.html.en revision d229f940abfb2490dee17979e9a5ff31b7012eb5
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<?xml version="1.0" encoding="ISO-8859-1"?>
530eba85dbd41b8a0fa5255d3648d1440199a661slive<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
e942c741056732f50da2074b36fe59805d370650slive<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!--
5f5d1b4cc970b7f06ff8ef6526128e9a27303d88nd XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd This file is generated from xml source: DO NOT EDIT
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding -->
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding<title>Apache HTTP Server 2.x Thread Safety Issues - Apache HTTP Server</title>
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding<link href="/style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding<link href="/style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding<link href="/style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="/style/css/prettify.css" />
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding<script src="/style/scripts/prettify.js" type="text/javascript">
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd</script>
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd<link href="/images/favicon.ico" rel="shortcut icon" /></head>
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd<body id="manual-page"><div id="page-header">
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p>
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd<p class="apache">Apache HTTP Server Version 2.5</p>
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd<img alt="" src="/images/feather.gif" /></div>
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd<div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="/images/left.gif" /></a></div>
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd<div id="path">
d5d794fc2f4cc9ca6d6da17cfa2cdcd8d244bacdnd<a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.5</a> &gt; <a href="./">Developer Documentation</a></div><div id="page-content"><div id="preamble"><h1>Apache HTTP Server 2.x Thread Safety Issues</h1>
7db9f691a00ead175b03335457ca296a33ddf31bnd<div class="toplang">
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<p><span>Available Languages: </span><a href="/en/developer/thread_safety.html" title="English">&nbsp;en&nbsp;</a></p>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive</div>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <p>When using any of the threaded mpms in the Apache HTTP Server 2.x it is important
530eba85dbd41b8a0fa5255d3648d1440199a661slive that every function called from Apache be thread safe. When linking in 3rd
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive party extensions it can be difficult to determine whether the resulting
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna server will be thread safe. Casual testing generally won't tell you this
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna either as thread safety problems can lead to subtle race conditions that
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna may only show up in certain conditions under heavy load.</p>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna</div>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna<div id="quickview"><ul id="toc"><li><img alt="" src="/images/down.gif" /> <a href="#variables">Global and static variables</a></li>
88d86cfadffe2275a3dfb67a4d7bdc018630b661rbowen<li><img alt="" src="/images/down.gif" /> <a href="#errno">errno</a></li>
88d86cfadffe2275a3dfb67a4d7bdc018630b661rbowen<li><img alt="" src="/images/down.gif" /> <a href="#functions">Common standard troublesome functions</a></li>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna<li><img alt="" src="/images/down.gif" /> <a href="#commonlibs">Common 3rd Party Libraries</a></li>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna<li><img alt="" src="/images/down.gif" /> <a href="#liblist">Library List</a></li>
e4e60c2f7ba8f12b687f588b89e413842e9f2d76igalic</ul></div>
e4e60c2f7ba8f12b687f588b89e413842e9f2d76igalic<div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
e4e60c2f7ba8f12b687f588b89e413842e9f2d76igalic<div class="section">
e4e60c2f7ba8f12b687f588b89e413842e9f2d76igalic<h2><a name="variables" id="variables">Global and static variables</a></h2>
e4e60c2f7ba8f12b687f588b89e413842e9f2d76igalic <p>When writing your module or when trying to determine if a module or
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor 3rd party library is thread safe there are some common things to keep in
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe mind.</p>
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe <p>First, you need to recognize that in a threaded model each individual
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor thread has its own program counter, stack and registers. Local variables
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe live on the stack, so those are fine. You need to watch out for any
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe static or global variables. This doesn't mean that you are absolutely not
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe allowed to use static or global variables. There are times when you
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna actually want something to affect all threads, but generally you need to
4e9f8c5414e5fe39b5393641533edca65f6e8b91poirier avoid using them if you want your code to be thread safe.</p>
4e9f8c5414e5fe39b5393641533edca65f6e8b91poirier
4e9f8c5414e5fe39b5393641533edca65f6e8b91poirier <p>In the case where you have a global variable that needs to be global and
4e9f8c5414e5fe39b5393641533edca65f6e8b91poirier accessed by all threads, be very careful when you update it. If, for
4e9f8c5414e5fe39b5393641533edca65f6e8b91poirier example, it is an incrementing counter, you need to atomically increment
4e9f8c5414e5fe39b5393641533edca65f6e8b91poirier it to avoid race conditions with other threads. You do this using a mutex
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna (mutual exclusion). Lock the mutex, read the current value, increment it
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna and write it back and then unlock the mutex. Any other thread that wants
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna to modify the value has to first check the mutex and block until it is
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna cleared.</p>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor <p>If you are using <a href="http://apr.apache.org/">APR</a>, have a look
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna at the <code>apr_atomic_<var>*</var></code> functions and the
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor <code>apr_thread_mutex_<var>*</var></code> functions.</p>
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor<div class="section">
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna<h2><a name="errno" id="errno">errno</a></h2>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna <p>This is a common global variable that holds the error number of the
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna last error that occurred. If one thread calls a low-level function that
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna sets errno and then another thread checks it, we are bleeding error
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna numbers from one thread into another. To solve this, make sure your
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna module or library defines <code>_REENTRANT</code> or is compiled with
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna <code>-D_REENTRANT</code>. This will make errno a per-thread variable
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna and should hopefully be transparent to the code. It does this by doing
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna something like this:</p>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor <div class="example"><p><code>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna #define errno (*(__errno_location()))
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor </code></p></div>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna <p>which means that accessing errno will call
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna <code>__errno_location()</code> which is provided by the libc. Setting
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe <code>_REENTRANT</code> also forces redefinition of some other functions
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe to their <code><var>*</var>_r</code> equivalents and sometimes changes
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe the common <code>getc</code>/<code>putc</code> macros into safer function
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe calls. Check your libc documentation for specifics. Instead of, or in
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe addition to <code>_REENTRANT</code> the symbols that may affect this are
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe <code>_POSIX_C_SOURCE</code>, <code>_THREAD_SAFE</code>,
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe <code>_SVID_SOURCE</code>, and <code>_BSD_SOURCE</code>.</p>
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe<div class="section">
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe<h2><a name="functions" id="functions">Common standard troublesome functions</a></h2>
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe <p>Not only do things have to be thread safe, but they also have to be
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe reentrant. <code>strtok()</code> is an obvious one. You call it the first
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe time with your delimiter which it then remembers and on each subsequent
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe call it returns the next token. Obviously if multiple threads are
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe calling it you will have a problem. Most systems have a reentrant version
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe of of the function called <code>strtok_r()</code> where you pass in an
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe extra argument which contains an allocated <code>char *</code> which the
e4e60c2f7ba8f12b687f588b89e413842e9f2d76igalic function will use instead of its own static storage for maintaining
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe the tokenizing state. If you are using <a href="http://apr.apache.org/">APR</a> you can use <code>apr_strtok()</code>.</p>
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe <p><code>crypt()</code> is another function that tends to not be reentrant,
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor so if you run across calls to that function in a library, watch out. On
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna some systems it is reentrant though, so it is not always a problem. If
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna your system has <code>crypt_r()</code> chances are you should be using
9f19223e8fb7b99f5f1cc02c8c3c2c6567793262rbowen that, or if possible simply avoid the whole mess by using md5 instead.</p>
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<div class="section">
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<h2><a name="commonlibs" id="commonlibs">Common 3rd Party Libraries</a></h2>
313bb560bc5c323cfd40c9cad7335b4b8e060aedkess <p>The following is a list of common libraries that are used by 3rd party
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive Apache modules. You can check to see if your module is using a potentially
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive unsafe library by using tools such as <code>ldd(1)</code> and
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <code>nm(1)</code>. For <a href="http://www.php.net/">PHP</a>, for example,
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive try this:</p>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive
18b4b0fd6056093002ddef488636bf5ebe415ef0erikabele <div class="example"><p><code>
88d86cfadffe2275a3dfb67a4d7bdc018630b661rbowen % ldd libphp4.so<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libsablot.so.0 =&gt; /usr/local/lib/libsablot.so.0 (0x401f6000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libexpat.so.0 =&gt; /usr/lib/libexpat.so.0 (0x402da000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libsnmp.so.0 =&gt; /usr/lib/libsnmp.so.0 (0x402f9000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libpdf.so.1 =&gt; /usr/local/lib/libpdf.so.1 (0x40353000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libz.so.1 =&gt; /usr/lib/libz.so.1 (0x403e2000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libpng.so.2 =&gt; /usr/lib/libpng.so.2 (0x403f0000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libmysqlclient.so.11 =&gt; /usr/lib/libmysqlclient.so.11 (0x40411000)<br />
fb77c505254b6e9c925e23e734463e87574f8f40kess libming.so =&gt; /usr/lib/libming.so (0x40449000)<br />
fb77c505254b6e9c925e23e734463e87574f8f40kess libm.so.6 =&gt; /lib/libm.so.6 (0x40487000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libfreetype.so.6 =&gt; /usr/lib/libfreetype.so.6 (0x404a8000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libjpeg.so.62 =&gt; /usr/lib/libjpeg.so.62 (0x404e7000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libcrypt.so.1 =&gt; /lib/libcrypt.so.1 (0x40505000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libssl.so.2 =&gt; /lib/libssl.so.2 (0x40532000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libcrypto.so.2 =&gt; /lib/libcrypto.so.2 (0x40560000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libresolv.so.2 =&gt; /lib/libresolv.so.2 (0x40624000)<br />
fb77c505254b6e9c925e23e734463e87574f8f40kess libdl.so.2 =&gt; /lib/libdl.so.2 (0x40634000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libnsl.so.1 =&gt; /lib/libnsl.so.1 (0x40637000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libc.so.6 =&gt; /lib/libc.so.6 (0x4064b000)<br />
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive /lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x80000000)
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive </code></p></div>
fb77c505254b6e9c925e23e734463e87574f8f40kess
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <p>In addition to these libraries you will need to have a look at any
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive libraries linked statically into the module. You can use <code>nm(1)</code>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive to look for individual symbols in the module.</p>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<div class="section">
fb77c505254b6e9c925e23e734463e87574f8f40kess<h2><a name="liblist" id="liblist">Library List</a></h2>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <p>Please drop a note to <a href="http://httpd.apache.org/lists.html#http-dev">dev@httpd.apache.org</a>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive if you have additions or corrections to this list.</p>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive
fb77c505254b6e9c925e23e734463e87574f8f40kess <table class="bordered"><tr class="header"><th>Library</th><th>Version</th><th>Thread Safe?</th><th>Notes</th></tr>
fb77c505254b6e9c925e23e734463e87574f8f40kess<tr><td><a href="http://aspell.sourceforge.net/">ASpell/PSpell</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>?</td>
fb77c505254b6e9c925e23e734463e87574f8f40kess <td> </td></tr>
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess<tr class="odd"><td><a href="http://www.sleepycat.com/">Berkeley DB</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>3.x, 4.x</td>
bc4b55ec8f31569d606d5680d50189a355bcd7a6rbowen <td>Yes</td>
fb77c505254b6e9c925e23e734463e87574f8f40kess <td>Be careful about sharing a connection across threads.</td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr><td><a href="http://sources.redhat.com/bzip2/index.html">bzip2</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>Yes</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>Both low-level and high-level APIs are thread-safe. However,
fb77c505254b6e9c925e23e734463e87574f8f40kess high-level API requires thread-safe access to errno.</td></tr>
fb77c505254b6e9c925e23e734463e87574f8f40kess<tr class="odd"><td><a href="http://cr.yp.to/cdb.html">cdb</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td>
fb77c505254b6e9c925e23e734463e87574f8f40kess <td>?</td>
fb77c505254b6e9c925e23e734463e87574f8f40kess <td> </td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr><td><a href="http://www.washington.edu/imap/">C-Client</a></td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td> </td>
130d299c4b2b15be45532a176604c71fdc7bea5bnd <td>Perhaps</td>
130d299c4b2b15be45532a176604c71fdc7bea5bnd <td>c-client uses <code>strtok()</code> and
130d299c4b2b15be45532a176604c71fdc7bea5bnd <code>gethostbyname()</code> which are not thread-safe on most C
130d299c4b2b15be45532a176604c71fdc7bea5bnd library implementations. c-client's static data is meant to be shared
130d299c4b2b15be45532a176604c71fdc7bea5bnd across threads. If <code>strtok()</code> and
ef8e89e090461194ecadd31e8796a2c51e0531a2kess <code>gethostbyname()</code> are thread-safe on your OS, c-client
130d299c4b2b15be45532a176604c71fdc7bea5bnd <em>may</em> be thread-safe.</td></tr>
130d299c4b2b15be45532a176604c71fdc7bea5bnd<tr class="odd"><td><a href="http://www.ijg.org/files/">libcrypt</a></td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td> </td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td>?</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr><td><a href="http://expat.sourceforge.net/">Expat</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>Yes</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>Need a separate parser instance per thread</td></tr>
003f0c9fda6664daf5092a0e42f65ede20098153slive<tr class="odd"><td><a href="http://www.freetds.org/">FreeTDS</a></td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td> </td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>?</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr><td><a href="http://www.freetype.org/">FreeType</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>?</td>
313bb560bc5c323cfd40c9cad7335b4b8e060aedkess <td> </td></tr>
003f0c9fda6664daf5092a0e42f65ede20098153slive<tr class="odd"><td><a href="http://www.boutell.com/gd/">GD 1.8.x</a></td>
003f0c9fda6664daf5092a0e42f65ede20098153slive <td> </td>
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess <td>?</td>
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess <td> </td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr><td><a href="http://www.boutell.com/gd/">GD 2.0.x</a></td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td> </td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td>?</td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td> </td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr class="odd"><td><a href="http://www.gnu.org/software/gdbm/gdbm.html">gdbm</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>No</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>Errors returned via a static <code>gdbm_error</code>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive variable</td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr><td><a href="http://www.imagemagick.org/">ImageMagick</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>5.2.2</td>
130d299c4b2b15be45532a176604c71fdc7bea5bnd <td>Yes</td>
130d299c4b2b15be45532a176604c71fdc7bea5bnd <td>ImageMagick docs claim it is thread safe since version 5.2.2 (see <a href="http://www.imagemagick.com/www/changelog.html">Change log</a>).
130d299c4b2b15be45532a176604c71fdc7bea5bnd </td></tr>
130d299c4b2b15be45532a176604c71fdc7bea5bnd<tr class="odd"><td><a href="http://www.enlightenment.org/p.php?p=about/efl&amp;l=en">Imlib2</a></td>
130d299c4b2b15be45532a176604c71fdc7bea5bnd <td> </td>
130d299c4b2b15be45532a176604c71fdc7bea5bnd <td>?</td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td> </td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr><td><a href="http://www.ijg.org/files/">libjpeg</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>v6b</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>?</td>
1a3f62ca37273a15a06bb94a61d3c6fcf4bf38c9rbowen <td> </td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr class="odd"><td><a href="http://mysql.com">libmysqlclient</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>Yes</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>Use mysqlclient_r library variant to ensure thread-safety. For
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding more information, please read <a href="http://dev.mysql.com/doc/mysql/en/Threaded_clients.html">http://dev.mysql.com/doc/mysql/en/Threaded_clients.html</a>.</td></tr>
684f2a9a422185adda0692a1203c5ad6687fc5c5nd<tr><td><a href="http://www.opaque.net/ming/">Ming</a></td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td>0.2a</td>
530eba85dbd41b8a0fa5255d3648d1440199a661slive <td>?</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr class="odd"><td><a href="http://net-snmp.sourceforge.net/">Net-SNMP</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>5.0.x</td>
003f0c9fda6664daf5092a0e42f65ede20098153slive <td>?</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td></tr>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive<tr><td><a href="http://www.openldap.org/">OpenLDAP</a></td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>2.1.x</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>Yes</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>Use <code>ldap_r</code> library variant to ensure
684f2a9a422185adda0692a1203c5ad6687fc5c5nd thread-safety.</td></tr>
a8ce9095d102e43fecb81093a132b90b9a227f78kess<tr class="odd"><td><a href="http://www.openssl.org/">OpenSSL</a></td>
684f2a9a422185adda0692a1203c5ad6687fc5c5nd <td>0.9.6g</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>Yes</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>Requires proper usage of <code>CRYPTO_num_locks</code>,
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <code>CRYPTO_set_locking_callback</code>,
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <code>CRYPTO_set_id_callback</code></td></tr>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding<tr><td><a href="http://www.oracle.com/">liboci8 (Oracle 8+)</a></td>
b24c77ceb4cea5ffa92536e19f0aa83608960dc4fielding <td>8.x,9.x</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>?</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td> </td></tr>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd<tr class="odd"><td><a href="http://pdflib.com/">pdflib</a></td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td>5.0.x</td>
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd <td>Yes</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>PDFLib docs claim it is thread safe; changes.txt indicates it
684f2a9a422185adda0692a1203c5ad6687fc5c5nd has been partially thread-safe since V1.91: <a href="http://www.pdflib.com/products/pdflib-family/pdflib/">http://www.pdflib.com/products/pdflib-family/pdflib/</a>.</td></tr>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding<tr><td><a href="http://www.libpng.org/pub/png/libpng.html">libpng</a></td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>1.0.x</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>?</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td> </td></tr>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding<tr class="odd"><td><a href="http://www.libpng.org/pub/png/libpng.html">libpng</a></td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>1.2.x</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>?</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td> </td></tr>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding<tr><td><a href="http://www.postgresql.org/docs/8.4/static/libpq-threading.html">libpq (PostgreSQL)</a></td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>8.x</td>
843a03fe0b138a4c1f64cb90a014e9417ac30691fielding <td>Yes</td>
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <td>Don't share connections across threads and watch out for
80c4526970a11f37c0f8e3b82afdf03902dac3f3slive <code>crypt()</code> calls</td></tr>
77ead9e0262e4f08ec336d1a65b2edef7705c839nd<tr class="odd"><td><a href="http://www.gingerall.com/charlie/ga/xml/p_sab.xml">Sablotron</a></td>
77ead9e0262e4f08ec336d1a65b2edef7705c839nd <td>0.95</td>
9583adab6bc4b3758e41963c905d9dad9f067131nd <td>?</td>
77ead9e0262e4f08ec336d1a65b2edef7705c839nd <td /></tr>
3770ed746d69c7a4111cba9966169bd5d7a509a6poirier<tr><td><a href="http://www.gzip.org/zlib/">zlib</a></td>
77ead9e0262e4f08ec336d1a65b2edef7705c839nd <td>1.1.4</td>
77ead9e0262e4f08ec336d1a65b2edef7705c839nd <td>Yes</td>
77ead9e0262e4f08ec336d1a65b2edef7705c839nd <td>Relies upon thread-safe zalloc and zfree functions Default is to
3770ed746d69c7a4111cba9966169bd5d7a509a6poirier use libc's calloc/free which are thread-safe.</td></tr>
3770ed746d69c7a4111cba9966169bd5d7a509a6poirier</table>
77ead9e0262e4f08ec336d1a65b2edef7705c839nd</div></div>
77ead9e0262e4f08ec336d1a65b2edef7705c839nd<div class="bottomlang">
77ead9e0262e4f08ec336d1a65b2edef7705c839nd<p><span>Available Languages: </span><a href="/en/developer/thread_safety.html" title="English">&nbsp;en&nbsp;</a></p>
77ead9e0262e4f08ec336d1a65b2edef7705c839nd</div><div id="footer">
77ead9e0262e4f08ec336d1a65b2edef7705c839nd<p class="apache">Copyright 2012 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
3770ed746d69c7a4111cba9966169bd5d7a509a6poirier<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
3770ed746d69c7a4111cba9966169bd5d7a509a6poirierif (typeof(prettyPrint) !== undefined) {
3770ed746d69c7a4111cba9966169bd5d7a509a6poirier prettyPrint();
3770ed746d69c7a4111cba9966169bd5d7a509a6poirier}
3770ed746d69c7a4111cba9966169bd5d7a509a6poirier//--><!]]></script>
3770ed746d69c7a4111cba9966169bd5d7a509a6poirier</body></html>