Hi Marian,

Thanks for your reply!

What I meant with blocking is exactly what you described:

"any in-progress fprintf which has taken the lock on a given FILE will mutually 
exclude any other fprintf from starting progress on the same FILE"

I.e. if one thread is still writing, the fprintf from another thread will not 
return immediately.
IMHO this could be an issue when there are really a lot of threads.

I became aware of the whole topic because some other projects use queues and 
dedicated write threads for logging...

Cheers,
Till

March 4, 2025 10:26 PM, "Marian Beermann" <[email protected] 
(mailto:[email protected]?to=%22Marian%20Beermann%22%20<[email protected]>)> 
wrote:
        I'm not sure what you mean by blocking here, but I'm pretty sure it's 
not an issue either way.

        These are all blocking file I/O, though normally the page cache will 
absorb any writes. Note that fflush(3) just flushes the FILE* buffers to the 
file descriptor. It doesn't fsync(2) (which may block for I/O for some time).

        There's also a lock in FILE* which is taken by the buffered I/O 
functions. That's what makes these thread-safe. Naturally, any in-progress 
fprintf which has taken the lock on a given FILE will mutually exclude any 
other fprintf from starting progress on the same FILE.

        Cheers, Marian
On 3/4/25 21:25, [email protected] (mailto:[email protected]) wrote: Hi 
there!

I never thought about this... until now: I'm using libssh in a multithreaded 
application and I'm logging from within the threads, using the lib's logging 
functions.
I'm quite sure that this isn't an issue as long as the output goes to stderr.

But I added a callback (ssh_set_log_callback) which writes the messages to a 
file handle, like:
logging_cb( ... )
{
fprintf(log_fd, "[%s, %d] %s - %sn", date, verbosity, (char *)userdata, buffer);
fflush(log_fd);
}

fprintf() is thread-safe. But can it block? In other words: Could one thread 
temporarily block another because of the logging?

So far I couldn't observe any blocking. But to be honest, I'm not sure why it 
works fine.
Maybe the OS layer write buffer is simply big enough to "take it all"?

Cheers
Till

Reply via email to