Blame THREADING.md

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