|
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.
|