Blame THREADING.md

Packit ae9e2a
Threads in libgit2
Packit ae9e2a
==================
Packit ae9e2a
Packit ae9e2a
You may safely use any libgit2 object from any thread, though there
Packit ae9e2a
may be issues depending on the cryptographic libraries libgit2 or its
Packit ae9e2a
dependencies link to (more on this later). For libgit2 itself,
Packit ae9e2a
provided you take the following into consideration you won't run into
Packit ae9e2a
issues:
Packit ae9e2a
Packit ae9e2a
Sharing objects
Packit ae9e2a
---------------
Packit ae9e2a
Packit ae9e2a
Use an object from a single thread at a time. Most data structures do
Packit ae9e2a
not guard against concurrent access themselves. This is because they
Packit ae9e2a
are rarely used in isolation and it makes more sense to synchronize
Packit ae9e2a
access via a larger lock or similar mechanism.
Packit ae9e2a
Packit ae9e2a
There are some objects which are read-only/immutable and are thus safe
Packit ae9e2a
to share across threads, such as references and configuration
Packit ae9e2a
snapshots.
Packit ae9e2a
Packit ae9e2a
Error messages
Packit ae9e2a
--------------
Packit ae9e2a
Packit ae9e2a
The error message is thread-local. The `giterr_last()` call must
Packit ae9e2a
happen on the same thread as the error in order to get the
Packit ae9e2a
message. Often this will be the case regardless, but if you use
Packit ae9e2a
something like the [GCD](http://en.wikipedia.org/wiki/Grand_Central_Dispatch)
Packit ae9e2a
on Mac OS X (where code is executed on an arbitrary thread), the code
Packit ae9e2a
must make sure to retrieve the error code on the thread where the error
Packit ae9e2a
happened.
Packit ae9e2a
Packit ae9e2a
Threads and cryptographic libraries
Packit ae9e2a
=======================================
Packit ae9e2a
Packit ae9e2a
On Windows
Packit ae9e2a
----------
Packit ae9e2a
Packit ae9e2a
When built as a native Windows DLL, libgit2 uses WinCNG and WinHTTP,
Packit ae9e2a
both of which are thread-safe. You do not need to do anything special.
Packit ae9e2a
Packit ae9e2a
When using libssh2 which itself uses WinCNG, there are no special
Packit ae9e2a
steps necessary. If you are using a MinGW or similar environment where
Packit ae9e2a
libssh2 uses OpenSSL or libgcrypt, then the general case affects
Packit ae9e2a
you.
Packit ae9e2a
Packit ae9e2a
On Mac OS X
Packit ae9e2a
-----------
Packit ae9e2a
Packit ae9e2a
By default we use libcurl to perform the encryption. The
Packit ae9e2a
system-provided libcurl uses SecureTransport, so no special steps are
Packit ae9e2a
necessary. If you link against another libcurl (e.g. from homebrew)
Packit ae9e2a
refer to the general case.
Packit ae9e2a
Packit ae9e2a
If the option to use libcurl was deactivated, the library makes use of
Packit ae9e2a
CommonCrypto and SecureTransport for cryptographic support. These are
Packit ae9e2a
thread-safe and you do not need to do anything special.
Packit ae9e2a
Packit ae9e2a
Note that libssh2 may still use OpenSSL itself. In that case, the
Packit ae9e2a
general case still affects you if you use ssh.
Packit ae9e2a
Packit ae9e2a
General Case
Packit ae9e2a
------------
Packit ae9e2a
Packit ae9e2a
If it's available, by default we use libcurl to provide HTTP tunneling support,
Packit ae9e2a
which may be linked against a number of cryptographic libraries and has its
Packit ae9e2a
own
Packit ae9e2a
[recommendations for thread safety](https://curl.haxx.se/libcurl/c/threadsafe.html).
Packit ae9e2a
Packit ae9e2a
If there are no alternative TLS implementations (currently only
Packit ae9e2a
SecureTransport), libgit2 uses OpenSSL in order to use HTTPS as a transport.
Packit ae9e2a
OpenSSL is thread-safe starting at version 1.1.0. If your copy of libgit2 is
Packit ae9e2a
linked against that version, you do not need to take any further steps.
Packit ae9e2a
Packit ae9e2a
Older versions of OpenSSL are made to be thread-implementation agnostic, and the
Packit ae9e2a
users of the library must set which locking function it should use. libgit2
Packit ae9e2a
cannot know what to set as the user of libgit2 may also be using OpenSSL independently and
Packit ae9e2a
the locking settings must then live outside the lifetime of libgit2.
Packit ae9e2a
Packit ae9e2a
Even if libgit2 doesn't use OpenSSL directly, OpenSSL can still be used by
Packit ae9e2a
libssh2 or libcurl depending on the configuration. If OpenSSL is used by
Packit ae9e2a
more than one library, you only need to set up threading for OpenSSL once.
Packit ae9e2a
Packit ae9e2a
If libgit2 is linked against OpenSSL, it provides a last-resort convenience function
Packit ae9e2a
`git_openssl_set_locking()` (available in `sys/openssl.h`) to use the
Packit ae9e2a
platform-native mutex mechanisms to perform the locking, which you can use
Packit ae9e2a
if you do not want to use OpenSSL outside of libgit2, or you
Packit ae9e2a
know that libgit2 will outlive the rest of the operations. It is then not
Packit ae9e2a
safe to use OpenSSL multi-threaded after libgit2's shutdown function
Packit ae9e2a
has been called.  Note `git_openssl_set_locking()` only works if
Packit ae9e2a
libgit2 uses OpenSSL directly - if OpenSSL is only used as a dependency
Packit ae9e2a
of libssh2 or libcurl as described above, `git_openssl_set_locking()` is a no-op.
Packit ae9e2a
Packit ae9e2a
If your programming language offers a package/bindings for OpenSSL,
Packit ae9e2a
you should very strongly prefer to use that in order to set up
Packit ae9e2a
locking, as they provide a level of coordination which is impossible
Packit ae9e2a
when using this function.
Packit ae9e2a
Packit ae9e2a
See the
Packit ae9e2a
[OpenSSL documentation](https://www.openssl.org/docs/crypto/threads.html)
Packit ae9e2a
on threading for more details, and http://trac.libssh2.org/wiki/MultiThreading
Packit ae9e2a
for a specific example of providing the threading callbacks.
Packit ae9e2a
Packit ae9e2a
libssh2 may be linked against OpenSSL or libgcrypt. If it uses OpenSSL,
Packit ae9e2a
see the above paragraphs. If it uses libgcrypt, then you need to
Packit ae9e2a
set up its locking before using it multi-threaded. libgit2 has no
Packit ae9e2a
direct connection to libgcrypt and thus has no convenience functions for
Packit ae9e2a
it (but libgcrypt has macros). Read libgcrypt's
Packit ae9e2a
[threading documentation for more information](http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html)
Packit ae9e2a
Packit ae9e2a
It is your responsibility as an application author or packager to know
Packit ae9e2a
what your dependencies are linked against and to take the appropriate
Packit ae9e2a
steps to ensure the cryptographic libraries are thread-safe. We agree
Packit ae9e2a
that this situation is far from ideal but at this time it is something
Packit ae9e2a
the application authors need to deal with.