-2

I am writing a Qt application using the libgit2 API. Certain functions are obviously placed in a background thread:

git_remote_fetch

Others are easily done inline in the foreground thread (i.e., validation within a clicked slot):

git_reference_is_valid_name

However, there are a number of calls for which it is not clear if they should be placed in a background thread or not. I could err on the side of caution, and put everything in a background thread. Or, for convenience, I could put local operations in the foreground unless I run into performance problems (i.e., status). I don't necessarily like the latter option, because if an operation is quick for me, I can't necessarily guarantee it will be quick every time for everyone else.

Are there any sort of threading guidelines or recommendations for libgit2? It doesn't seem to be addressed by the documentation, and information is somewhat sparse.

Update: Specifically, by threading guidelines, I am looking for documentation on recommendations for using specific functions in the foreground or in a background worker task, rather than thread-safeness. For now, I have resorted to placing local operations in a foreground task unless they produce performance problems.

Dan Paulat
  • 152
  • 6

2 Answers2

1

Are there any sort of threading guidelines or recommendations for libgit2? It doesn't seem to be addressed by the documentation, and information is somewhat sparse.

Yes there are.

Initialization

The library needs to keep track of some global state. Call

git_libgit2_init();

before calling any other libgit2 functions. You can call this function many times. A matching number of calls to

git_libgit2_shutdown(); 

will free the resources. Note that if you have worker threads, you should call git_libgit2_shutdown after those threads have exited. If you require assistance coordinating this, simply have the worker threads call git_libgit2_init at startup and git_libgit2_shutdown at shutdown.

You may safely use any libgit2 object from any thread, though there may be issues depending on the cryptographic libraries libgit2 or its dependencies link to (more on this later). For libgit2 itself, provided you take the following into consideration you won't run into issues:

Sharing objects

Use an object from a single thread at a time. Most data structures do not guard against concurrent access themselves. This is because they are rarely used in isolation and it makes more sense to synchronize access via a larger lock or similar mechanism. There are some objects which are read-only/immutable and are thus safe to share across threads, such as references and configuration snapshots.

nulltoken
  • 64,429
  • 20
  • 138
  • 130
1

Those guidelines would be the same as for any other library or code. If it's not immediate, you put it in a background thread and free up the UI thread until it's done.

git/libgit2 is mostly about I/O (except for the accessors, which you can tell apart because they return a value instead of an error code), which means it's generally going to take an unknown amount of time to perform any action.

Depending on what's happened since the last call to libgit2, it may need to update its list of what packfiles there are, or it might need to read the full packed refs file instead of just the one. And this just gets worse if the filesystem is on a different computer.

Due to the I/O and a filesystem being anywhere in the world, anything that's not an accessor can take an unbounded amount of time. Which operations you want to call on the UI thread depend on which assumptions yo're willing to make about the locality and freshness of the data at any point in time.

Carlos Martín Nieto
  • 5,207
  • 1
  • 15
  • 16