En faisant un montage dans une classe avec un long historique, j'ai été bloqué par une habitude particulière de l'architecte d'encapsuler sa séquence va_start -> va_end dans un mutex. Le changelog pour cette addition (qui a été faite il y a une quinzaine d'années, et non révisé depuis) a noté que c'était parce que va_start et. tout n'était pas réentrant.Va_start (etc.) est-il réentrant?
Je n'étais pas au courant de ces problèmes avec va_start, car j'ai toujours pensé que c'était juste une macro pour certains calculs de pile-pointeur. Y a-t-il quelque chose que je ne connais pas? Je ne veux pas changer ce code s'il y a des effets secondaires.
Plus précisément, la fonction en question ressemble beaucoup à ceci:
void write(const char *format, ...)
{
mutex.Lock();
va_list args;
va_start(args, format);
_write(format, args);
va_end(args);
mutex.Unlock();
}
Ceci est appelé à partir de plusieurs threads.
Si les verrous de commande _write l'IO série à un niveau octet ou niveau en mémoire tampon, vous pouvez toujours vouloir avoir un verrou de niveau supérieur pour rendre l'écriture() appellent plus atomique. Il n'y a rien de plus énervant à avoir 2 threads appellent 'printf (" foo ")' et 'printf (" bar ")' et obtenir '" fboaor "' sur votre sortie, au lieu de '' foobar ''ou' 'barfoo' ' . –