diff --git a/inc/lektor/common.h b/inc/lektor/common.h index 34e3bd09aaf3691f3eb76ce49d22bce04aedf9a4..12cea20343d4b5f0ff8524ec938046bd0be1788a 100644 --- a/inc/lektor/common.h +++ b/inc/lektor/common.h @@ -60,10 +60,19 @@ enum log_level { }; extern enum log_level __log_level; void __lkt_log(enum log_level, const char *section, const char *func, const char *format, ...); +void __lkt_log_continuation(enum log_level, const char *format, ...); +void __lkt_log_lock(enum log_level); +void __lkt_log_unlock(enum log_level); #define LOG_INFO( section, ...) __lkt_log(INFO, section, __func__, __VA_ARGS__) #define LOG_WARN( section, ...) __lkt_log(WARN, section, __func__, __VA_ARGS__) #define LOG_ERROR(section, ...) __lkt_log(ERROR, section, __func__, __VA_ARGS__) #define LOG_DEBUG(section, ...) __lkt_log(DEBUG, section, __func__, __VA_ARGS__) +#define LOG_INFO_CONT( ...) __lkt_log_continuation(INFO, __VA_ARGS__) +#define LOG_WARN_CONT( ...) __lkt_log_continuation(INFO, __VA_ARGS__) +#define LOG_ERROR_CONT(...) __lkt_log_continuation(INFO, __VA_ARGS__) +#define LOG_DEBUG_CONT(...) __lkt_log_continuation(INFO, __VA_ARGS__) +#define LOG_LOCK(level) __lkt_log_lock(level) +#define LOG_UNLOCK(level) __lkt_log_unlock(level) #define SELF_EXECUTABLE_LINUX "/proc/self/exe" #define SELF_EXECUTABLE_FREEBSD "/proc/curproc/file" diff --git a/src/base/common.c b/src/base/common.c index 4b72f9e055a45afa4a24392e53b68485cae95ae5..7cd1c39ed97609904455929d37f8d10cf474666e 100644 --- a/src/base/common.c +++ b/src/base/common.c @@ -9,6 +9,7 @@ #include <time.h> #include <sys/stat.h> #include <sys/time.h> +#include <pthread.h> /* Assert function */ @@ -38,7 +39,34 @@ __set_assert(void) /* Log functions */ -enum log_level __log_level = __LAST_UNUSED_LOG_LEVEL; /* All by default */ +enum log_level __log_level = __LAST_UNUSED_LOG_LEVEL; /* All by default */ +static pthread_mutex_t __log_mutex; /* One thread can lock at the time */ + +__attribute__((constructor)) static void +___lkt_init_log_mutex(void) +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&__log_mutex, &attr); + pthread_mutexattr_destroy(&attr); +} + +void +__lkt_log_lock(enum log_level level) +{ + if (level > __log_level) + return; + RETURN_IF(pthread_mutex_lock(&__log_mutex), "Failed to lock, not logging anything", NOTHING); +} + +void +__lkt_log_unlock(enum log_level level) +{ + if (level > __log_level) + return; + RETURN_IF(pthread_mutex_unlock(&__log_mutex), "Unlock failed, logging may be broken", NOTHING); +} void __lkt_log(enum log_level level, const char *section, const char *func, const char *format, ...) @@ -58,14 +86,40 @@ __lkt_log(enum log_level level, const char *section, const char *func, const cha #define SEC_PER_HOUR 3600 #define SEC_PER_MIN 60 + if (level > __log_level) + return; + + RETURN_IF(pthread_mutex_lock(&__log_mutex), "Failed to lock, not logging anything", NOTHING); + + safe_snprintf(line, LKT_MESSAGE_MAX, " %c [%02d:%02d:%02d] %-10s %s: %s\n", + level == ERROR ? '!' : level == WARN ? '*' : level == INFO ? '.' : ' ', + hour, min, sec, + section, func, format); + + va_start(ap, format); + vfprintf(stderr, line, ap); + va_end(ap); + + RETURN_IF(pthread_mutex_unlock(&__log_mutex), "Unlock failed, logging may be broken", NOTHING); +} + +void +__lkt_log_continuation(enum log_level level, const char *format, ...) +{ + char line[LKT_MESSAGE_MAX]; + va_list ap; + if (level <= __log_level) { - safe_snprintf(line, LKT_MESSAGE_MAX, " %c [%02d:%02d:%02d] %-10s %s: %s\n", - level == ERROR ? '!' : level == WARN ? '*' : level == INFO ? '.' : ' ', - hour, min, sec, - section, func, format); + RETURN_IF(pthread_mutex_lock(&__log_mutex), "Failed to lock, " + "not logging anything", NOTHING); + + safe_snprintf(line, LKT_MESSAGE_MAX, "\t... %s\n", format); va_start(ap, format); vfprintf(stderr, line, ap); va_end(ap); + + RETURN_IF(pthread_mutex_unlock(&__log_mutex), "Failed to unlock, " + "logging may be broken", NOTHING); } } diff --git a/src/base/config.c b/src/base/config.c index 90e73d665ed5ba2bf3e8ace1008b80acd726f84a..5a6165531a1ebb588cf703041840f88335c8838e 100644 --- a/src/base/config.c +++ b/src/base/config.c @@ -51,8 +51,7 @@ static inline void __set_log_level(const char *name, const char *level) { if (!STR_MATCH(name, "log")) { - LOG_WARN("CONFIG", "Invalid option '%s[:=]%s' with no section", - name, level); + LOG_WARN_CONT("Invalid option '%s[:=]%s' with no section", name, level); return; } @@ -72,7 +71,7 @@ __set_log_level(const char *name, const char *level) else __log_level = strtol(level, NULL, 0); - LOG_INFO("CONFIG", "Log level set to %d", __log_level); + LOG_INFO_CONT("Log level set to %d", __log_level); } static inline int @@ -90,6 +89,8 @@ ini_parse(const char *path, volatile sqlite3 *db) memset(section, 0, LKT_LINE_MAX); memset(line, 0, LKT_LINE_MAX); + LOG_INFO("CONFIG", "Save config to database from file"); + /* Parse the file */ while (NULL != fgets(line, LKT_LINE_MAX, file)) { ++linenum; diff --git a/src/database/config.c b/src/database/config.c index ef56bb4c7ba3b81b11715ac9223d0be581ed5840..00055e11757f6f7f7a150272fd2d4a728d341bb6 100644 --- a/src/database/config.c +++ b/src/database/config.c @@ -34,7 +34,7 @@ database_config_set(volatile sqlite3 *db, const char *section, const char *key, goto error; } - LOG_INFO("CONFIG", "Set [%s.%s] to %s", section, key, value); + LOG_INFO_CONT("Set [%s.%s] to %s", section, key, value); ret = true; error: sqlite3_finalize(stmt); diff --git a/src/module/module_repo.c b/src/module/module_repo.c index 726d5705902fde9efa12ad6faae95933d3e1497b..afe682b2a759f42523d23617a8c6da1e566bf215 100644 --- a/src/module/module_repo.c +++ b/src/module/module_repo.c @@ -464,6 +464,37 @@ __worker_rescan(void *__repo) pthread_exit(NULL); } +static void * +__worker_import_favorites(void *__repo) +{ + struct module_repo_internal *repo = __repo; + + // GOTO_IF(pthread_mutex_lock(&(repo->mtx)), "Failed to lock", end_no_lock); + // repo->updating &= REPO_UPDATE_FAV; + // GOTO_IF(pthread_mutex_unlock(&(repo->mtx)), "Failed to unlock", end_no_lock); + + // // struct json_object *json; + // LOG_INFO("REPO", "Download favorite lists from %s (%s), directory is %s", + // repo->name, repo->get_all_json, repo->kara_dir); + // // if (__json_sync(repo, &json)) { + // // LOG_ERROR("REPO", "Failed to get json, possibly no internet connexion or repo is down"); + // // pthread_exit(NULL); + // // } + // // __handle_got_json(repo->db, repo, json); + // // LOG_INFO("REPO", "Finished to download and insert kara list"); + // // json_object_put(json); + // // __handle_deleted_kara(repo->db); + // // LOG_INFO("REPO", "Finished to deal with deleted kara"); + // // database_updated(repo->db); + + // GOTO_IF(pthread_mutex_lock(&(repo->mtx)), "Failed to lock", end_no_lock); + // repo->updating &= (~ REPO_UPDATE_FAV); + // GOTO_IF(pthread_mutex_unlock(&(repo->mtx)), "Failed to unlock", end_no_lock); + +end_no_lock: + pthread_exit(NULL); +} + /*********************************************** * Functions that will be wrapped and exported * ***********************************************/