connection: Make wl_closure_print output atomic

When multiple threads are used, output from different threads was intermixed in one line. That what breaking parsing of the log messages. Now, intermixing is prevented by using a memstream.

Signed-off-by: Alexander Irion <alexander_irion@mentor.com>
This commit is contained in:
Alexander Irion 2022-03-07 15:49:49 +01:00
parent af8b5c0782
commit ca4678354c

View file

@ -1272,11 +1272,18 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target,
struct timespec tp; struct timespec tp;
unsigned int time; unsigned int time;
uint32_t nval; uint32_t nval;
FILE *f;
char *buffer;
size_t buffer_length;
f = open_memstream(&buffer, &buffer_length);
if (f == NULL)
return;
clock_gettime(CLOCK_REALTIME, &tp); clock_gettime(CLOCK_REALTIME, &tp);
time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
fprintf(stderr, "[%7u.%03u] %s%s%s@%u.%s(", fprintf(f, "[%7u.%03u] %s%s%s@%u.%s(",
time / 1000, time % 1000, time / 1000, time % 1000,
discarded ? "discarded " : "", discarded ? "discarded " : "",
send ? " -> " : "", send ? " -> " : "",
@ -1286,41 +1293,41 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target,
for (i = 0; i < closure->count; i++) { for (i = 0; i < closure->count; i++) {
signature = get_next_argument(signature, &arg); signature = get_next_argument(signature, &arg);
if (i > 0) if (i > 0)
fprintf(stderr, ", "); fprintf(f, ", ");
switch (arg.type) { switch (arg.type) {
case 'u': case 'u':
fprintf(stderr, "%u", closure->args[i].u); fprintf(f, "%u", closure->args[i].u);
break; break;
case 'i': case 'i':
fprintf(stderr, "%d", closure->args[i].i); fprintf(f, "%d", closure->args[i].i);
break; break;
case 'f': case 'f':
/* The magic number 390625 is 1e8 / 256 */ /* The magic number 390625 is 1e8 / 256 */
if (closure->args[i].f >= 0) { if (closure->args[i].f >= 0) {
fprintf(stderr, "%d.%08d", fprintf(f, "%d.%08d",
closure->args[i].f / 256, closure->args[i].f / 256,
390625 * (closure->args[i].f % 256)); 390625 * (closure->args[i].f % 256));
} else { } else {
fprintf(stderr, "-%d.%08d", fprintf(f, "-%d.%08d",
closure->args[i].f / -256, closure->args[i].f / -256,
-390625 * (closure->args[i].f % 256)); -390625 * (closure->args[i].f % 256));
} }
break; break;
case 's': case 's':
if (closure->args[i].s) if (closure->args[i].s)
fprintf(stderr, "\"%s\"", closure->args[i].s); fprintf(f, "\"%s\"", closure->args[i].s);
else else
fprintf(stderr, "nil"); fprintf(f, "nil");
break; break;
case 'o': case 'o':
if (closure->args[i].o) if (closure->args[i].o)
fprintf(stderr, "%s@%u", fprintf(f, "%s@%u",
closure->args[i].o->interface->name, closure->args[i].o->interface->name,
closure->args[i].o->id); closure->args[i].o->id);
else else
fprintf(stderr, "nil"); fprintf(f, "nil");
break; break;
case 'n': case 'n':
if (n_parse) if (n_parse)
@ -1328,25 +1335,30 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target,
else else
nval = closure->args[i].n; nval = closure->args[i].n;
fprintf(stderr, "new id %s@", fprintf(f, "new id %s@",
(closure->message->types[i]) ? (closure->message->types[i]) ?
closure->message->types[i]->name : closure->message->types[i]->name :
"[unknown]"); "[unknown]");
if (nval != 0) if (nval != 0)
fprintf(stderr, "%u", nval); fprintf(f, "%u", nval);
else else
fprintf(stderr, "nil"); fprintf(f, "nil");
break; break;
case 'a': case 'a':
fprintf(stderr, "array[%zu]", closure->args[i].a->size); fprintf(f, "array[%zu]", closure->args[i].a->size);
break; break;
case 'h': case 'h':
fprintf(stderr, "fd %d", closure->args[i].h); fprintf(f, "fd %d", closure->args[i].h);
break; break;
} }
} }
fprintf(stderr, ")\n"); fprintf(f, ")\n");
if (fclose(f) == 0) {
fprintf(stderr, "%s", buffer);
free(buffer);
}
} }
static int static int