lib: make glib initialization thread-safe

In principle this could be done without depending on C++11 features,
but these features should be available since gcc 4.8.1, and this
localized usage is easy to replace if it turns out to be problematic
for portability.
This commit is contained in:
David Bremner 2021-05-09 17:33:48 -03:00
parent a34d7b4144
commit 8410be8e08
6 changed files with 56 additions and 48 deletions

View file

@ -62,7 +62,8 @@ libnotmuch_cxx_srcs = \
$(dir)/thread-fp.cc \ $(dir)/thread-fp.cc \
$(dir)/features.cc \ $(dir)/features.cc \
$(dir)/prefix.cc \ $(dir)/prefix.cc \
$(dir)/open.cc $(dir)/open.cc \
$(dir)/init.cc
libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o) libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o)

View file

@ -148,8 +148,6 @@ notmuch_filter_discard_non_term_class_init (NotmuchFilterDiscardNonTermClass *kl
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass); GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
parent_class = (GMimeFilterClass *) g_type_class_ref (GMIME_TYPE_FILTER);
object_class->finalize = notmuch_filter_discard_non_term_finalize; object_class->finalize = notmuch_filter_discard_non_term_finalize;
filter_class->copy = filter_copy; filter_class->copy = filter_copy;
@ -240,30 +238,33 @@ filter_reset (GMimeFilter *gmime_filter)
* *
* Returns: a new #NotmuchFilterDiscardNonTerm filter. * Returns: a new #NotmuchFilterDiscardNonTerm filter.
**/ **/
static GType type = 0;
static const GTypeInfo info = {
.class_size = sizeof (NotmuchFilterDiscardNonTermClass),
.base_init = NULL,
.base_finalize = NULL,
.class_init = (GClassInitFunc) notmuch_filter_discard_non_term_class_init,
.class_finalize = NULL,
.class_data = NULL,
.instance_size = sizeof (NotmuchFilterDiscardNonTerm),
.n_preallocs = 0,
.instance_init = NULL,
.value_table = NULL,
};
void
_notmuch_filter_init () {
type = g_type_register_static (GMIME_TYPE_FILTER, "NotmuchFilterDiscardNonTerm", &info,
(GTypeFlags) 0);
parent_class = (GMimeFilterClass *) g_type_class_ref (GMIME_TYPE_FILTER);
}
static GMimeFilter * static GMimeFilter *
notmuch_filter_discard_non_term_new (GMimeContentType *content_type) notmuch_filter_discard_non_term_new (GMimeContentType *content_type)
{ {
static GType type = 0;
NotmuchFilterDiscardNonTerm *filter; NotmuchFilterDiscardNonTerm *filter;
if (! type) {
static const GTypeInfo info = {
.class_size = sizeof (NotmuchFilterDiscardNonTermClass),
.base_init = NULL,
.base_finalize = NULL,
.class_init = (GClassInitFunc) notmuch_filter_discard_non_term_class_init,
.class_finalize = NULL,
.class_data = NULL,
.instance_size = sizeof (NotmuchFilterDiscardNonTerm),
.n_preallocs = 0,
.instance_init = NULL,
.value_table = NULL,
};
type = g_type_register_static (GMIME_TYPE_FILTER, "NotmuchFilterDiscardNonTerm", &info,
(GTypeFlags) 0);
}
filter = (NotmuchFilterDiscardNonTerm *) g_object_new (type, NULL); filter = (NotmuchFilterDiscardNonTerm *) g_object_new (type, NULL);
filter->content_type = content_type; filter->content_type = content_type;
filter->state = 0; filter->state = 0;

21
lib/init.cc Normal file
View file

@ -0,0 +1,21 @@
#include "notmuch-private.h"
#include <mutex>
static void do_init ()
{
/* Initialize the GLib type system and threads */
#if ! GLIB_CHECK_VERSION (2, 35, 1)
g_type_init ();
#endif
g_mime_init ();
_notmuch_filter_init ();
}
void
_notmuch_init ()
{
static std::once_flag initialized;
std::call_once (initialized, do_init);
}

View file

@ -141,7 +141,6 @@ _notmuch_message_file_parse (notmuch_message_file_t *message)
{ {
GMimeParser *parser; GMimeParser *parser;
notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
static int initialized = 0;
bool is_mbox; bool is_mbox;
if (message->message) if (message->message)
@ -149,10 +148,7 @@ _notmuch_message_file_parse (notmuch_message_file_t *message)
is_mbox = _is_mbox (message->stream); is_mbox = _is_mbox (message->stream);
if (! initialized) { _notmuch_init ();
g_mime_init ();
initialized = 1;
}
message->headers = g_hash_table_new_full (strcase_hash, strcase_equal, message->headers = g_hash_table_new_full (strcase_hash, strcase_equal,
free, g_free); free, g_free);

View file

@ -469,11 +469,18 @@ _notmuch_database_link_message_to_parents (notmuch_database_t *notmuch,
const char **thread_id); const char **thread_id);
/* index.cc */ /* index.cc */
void
_notmuch_filter_init ();
notmuch_status_t notmuch_status_t
_notmuch_message_index_file (notmuch_message_t *message, _notmuch_message_index_file (notmuch_message_t *message,
notmuch_indexopts_t *indexopts, notmuch_indexopts_t *indexopts,
notmuch_message_file_t *message_file); notmuch_message_file_t *message_file);
/* init.cc */
void
_notmuch_init ();
/* messages.c */ /* messages.c */
typedef struct _notmuch_message_node { typedef struct _notmuch_message_node {

View file

@ -307,24 +307,6 @@ _set_database_path (notmuch_database_t *notmuch,
_notmuch_config_cache (notmuch, NOTMUCH_CONFIG_DATABASE_PATH, path); _notmuch_config_cache (notmuch, NOTMUCH_CONFIG_DATABASE_PATH, path);
} }
static void
_init_libs ()
{
static int initialized = 0;
/* Initialize the GLib type system and threads */
#if ! GLIB_CHECK_VERSION (2, 35, 1)
g_type_init ();
#endif
/* Initialize gmime */
if (! initialized) {
g_mime_init ();
initialized = 1;
}
}
static void static void
_load_database_state (notmuch_database_t *notmuch) _load_database_state (notmuch_database_t *notmuch)
{ {
@ -498,7 +480,7 @@ notmuch_database_open_with_config (const char *database_path,
GKeyFile *key_file = NULL; GKeyFile *key_file = NULL;
bool split = false; bool split = false;
_init_libs (); _notmuch_init ();
notmuch = _alloc_notmuch (); notmuch = _alloc_notmuch ();
if (! notmuch) { if (! notmuch) {
@ -595,7 +577,7 @@ notmuch_database_create_with_config (const char *database_path,
int err; int err;
bool split = false; bool split = false;
_init_libs (); _notmuch_init ();
notmuch = _alloc_notmuch (); notmuch = _alloc_notmuch ();
if (! notmuch) { if (! notmuch) {
@ -791,7 +773,7 @@ notmuch_database_load_config (const char *database_path,
GKeyFile *key_file = NULL; GKeyFile *key_file = NULL;
bool split = false; bool split = false;
_init_libs (); _notmuch_init ();
notmuch = _alloc_notmuch (); notmuch = _alloc_notmuch ();
if (! notmuch) { if (! notmuch) {