Skip to content
Merged
19 changes: 11 additions & 8 deletions common/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ enum common_log_col : int {
};

// disable colors by default
static std::vector<const char *> g_col = {
static const char* g_col[] = {
"",
"",
"",
Expand Down Expand Up @@ -247,7 +247,6 @@ struct common_log {

entries = std::move(new_entries);
}

cv.notify_one();
}

Expand All @@ -265,7 +264,6 @@ struct common_log {
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]() { return head != tail; });

cur = entries[head];

head = (head + 1) % entries.size();
Expand Down Expand Up @@ -301,7 +299,6 @@ struct common_log {

tail = (tail + 1) % entries.size();
}

cv.notify_one();
}

Expand Down Expand Up @@ -338,7 +335,7 @@ struct common_log {
g_col[COMMON_LOG_COL_CYAN] = LOG_COL_CYAN;
g_col[COMMON_LOG_COL_WHITE] = LOG_COL_WHITE;
} else {
for (size_t i = 0; i < g_col.size(); i++) {
for (size_t i = 0; i < std::size(g_col); i++) {
g_col[i] = "";
}
}
Expand Down Expand Up @@ -368,14 +365,20 @@ struct common_log * common_log_init() {
}

struct common_log * common_log_main() {
static struct common_log log;
// We intentionally leak (i.e. do not delete) the logger singleton because
// common_log destructor called at DLL teardown phase will cause hanging on Windows.
// OS will release resources anyway so it should not be a significant issue,
// though this design may cause logs to be lost if not flushed before the program exits.
// Refer to https://github.com/ggml-org/llama.cpp/issues/22142 for details.
static struct common_log * log;
static std::once_flag init_flag;
std::call_once(init_flag, [&]() {
log = new common_log;
// Set default to auto-detect colors
log.set_colors(tty_can_use_colors());
log->set_colors(tty_can_use_colors());
});

return &log;
return log;
}

void common_log_pause(struct common_log * log) {
Expand Down
6 changes: 5 additions & 1 deletion common/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ void common_log_default_callback(enum ggml_log_level level, const char * text, v
struct common_log;

struct common_log * common_log_init();
struct common_log * common_log_main(); // singleton, automatically destroys itself on exit

// Singleton, intentionally leaked to avoid Windows teardown hangs.
// Call common_log_flush() before exit if you want to ensure all logs are flushed.
struct common_log * common_log_main();

void common_log_pause (struct common_log * log); // pause the worker thread, not thread-safe
void common_log_resume(struct common_log * log); // resume the worker thread, not thread-safe
void common_log_free (struct common_log * log);
Expand Down
4 changes: 4 additions & 0 deletions tests/test-log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,9 @@ int main() {
threads[i].join();
}

common_log_flush(common_log_main());
// We explicitly free the logger singleton to avoid hanging on Windows
// related to timing issues of thread startup and DLL teardown
common_log_free(common_log_main());
return 0;
}