weston-debug: Convert weston_debug_stream to use the subscriber base class

Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Suggested-by: Pekka Paalanen <pekka.paalanen@collabora.com>
dev
Marius Vlad 5 years ago
parent e0a858a5f2
commit 7814f301d1
  1. 25
      include/libweston/weston-debug.h
  2. 6
      libweston/compositor.c
  3. 239
      libweston/weston-debug.c

@ -49,14 +49,13 @@ struct weston_debug_stream;
/** weston_log_scope callback /** weston_log_scope callback
* *
* \param stream The debug stream. * @param scope The log scope.
* \param user_data The \c user_data argument given to * @param user_data The \c user_data argument given to
* weston_compositor_add_log_scope() * weston_compositor_add_log_scope()
* *
* \memberof weston_log_scope * @memberof weston_log_scope
* \sa weston_debug_stream
*/ */
typedef void (*weston_log_scope_cb)(struct weston_debug_stream *stream, typedef void (*weston_log_scope_cb)(struct weston_log_scope *scope,
void *user_data); void *user_data);
struct weston_log_scope * struct weston_log_scope *
@ -84,22 +83,8 @@ void
weston_log_scope_printf(struct weston_log_scope *scope, weston_log_scope_printf(struct weston_log_scope *scope,
const char *fmt, ...) const char *fmt, ...)
__attribute__ ((format (printf, 2, 3))); __attribute__ ((format (printf, 2, 3)));
void
weston_debug_stream_write(struct weston_debug_stream *stream,
const char *data, size_t len);
void
weston_debug_stream_vprintf(struct weston_debug_stream *stream,
const char *fmt, va_list ap);
void
weston_debug_stream_printf(struct weston_debug_stream *stream,
const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
void void
weston_debug_stream_complete(struct weston_debug_stream *stream); weston_log_scope_complete(struct weston_log_scope *scope);
char * char *
weston_log_scope_timestamp(struct weston_log_scope *scope, weston_log_scope_timestamp(struct weston_log_scope *scope,

@ -7143,14 +7143,14 @@ weston_compositor_print_scene_graph(struct weston_compositor *ec)
* and then terminates the stream. * and then terminates the stream.
*/ */
static void static void
debug_scene_graph_cb(struct weston_debug_stream *stream, void *data) debug_scene_graph_cb(struct weston_log_scope *scope, void *data)
{ {
struct weston_compositor *ec = data; struct weston_compositor *ec = data;
char *str = weston_compositor_print_scene_graph(ec); char *str = weston_compositor_print_scene_graph(ec);
weston_debug_stream_printf(stream, "%s", str); weston_log_scope_printf(scope, "%s", str);
free(str); free(str);
weston_debug_stream_complete(stream); weston_log_scope_complete(scope);
} }
/** Create the compositor. /** Create the compositor.

@ -77,7 +77,6 @@ struct weston_log_scope {
char *desc; char *desc;
weston_log_scope_cb begin_cb; weston_log_scope_cb begin_cb;
void *user_data; void *user_data;
struct wl_list stream_list; /**< weston_debug_stream::scope_link */
struct wl_list compositor_link; struct wl_list compositor_link;
struct wl_list subscription_list; /**< weston_log_subscription::source_link */ struct wl_list subscription_list; /**< weston_log_subscription::source_link */
}; };
@ -119,11 +118,17 @@ struct weston_log_subscription {
* same messages. * same messages.
*/ */
struct weston_debug_stream { struct weston_debug_stream {
struct weston_log_subscriber base;
int fd; /**< client provided fd */ int fd; /**< client provided fd */
struct wl_resource *resource; /**< weston_debug_stream_v1 object */ struct wl_resource *resource; /**< weston_debug_stream_v1 object */
struct wl_list scope_link;
}; };
static struct weston_debug_stream *
to_weston_debug_stream(struct weston_log_subscriber *sub)
{
return container_of(sub, struct weston_debug_stream, base);
}
/** Creates a new subscription using the subscriber by \c owner. /** Creates a new subscription using the subscriber by \c owner.
* *
* The subscription created is added to the \c owner subscription list. * The subscription created is added to the \c owner subscription list.
@ -254,9 +259,6 @@ stream_close_unlink(struct weston_debug_stream *stream)
if (stream->fd != -1) if (stream->fd != -1)
close(stream->fd); close(stream->fd);
stream->fd = -1; stream->fd = -1;
wl_list_remove(&stream->scope_link);
wl_list_init(&stream->scope_link);
} }
static void WL_PRINTF(2, 3) static void WL_PRINTF(2, 3)
@ -282,28 +284,107 @@ stream_close_on_failure(struct weston_debug_stream *stream,
} }
} }
/** Write data into a specific debug stream
*
* \param sub The subscriber's stream to write into; must not be NULL.
* \param[in] data Pointer to the data to write.
* \param len Number of bytes to write.
*
* Writes the given data (binary verbatim) into the debug stream.
* If \c len is zero or negative, the write is silently dropped.
*
* Writing is continued until all data has been written or
* a write fails. If the write fails due to a signal, it is re-tried.
* Otherwise on failure, the stream is closed and
* \c weston_debug_stream_v1.failure event is sent to the client.
*
* \memberof weston_debug_stream
*/
static void
weston_debug_stream_write(struct weston_log_subscriber *sub,
const char *data, size_t len)
{
ssize_t len_ = len;
ssize_t ret;
int e;
struct weston_debug_stream *stream = to_weston_debug_stream(sub);
if (stream->fd == -1)
return;
while (len_ > 0) {
ret = write(stream->fd, data, len_);
e = errno;
if (ret < 0) {
if (e == EINTR)
continue;
stream_close_on_failure(stream,
"Error writing %zd bytes: %s (%d)",
len_, strerror(e), e);
break;
}
len_ -= ret;
data += ret;
}
}
/** Close the debug stream and send success event
*
* \param sub Subscriber's stream to close.
*
* Closes the debug stream and sends \c weston_debug_stream_v1.complete
* event to the client. This tells the client the debug information dump
* is complete.
*
* \memberof weston_debug_stream
*/
static void
weston_debug_stream_complete(struct weston_log_subscriber *sub)
{
struct weston_debug_stream *stream = to_weston_debug_stream(sub);
stream_close_unlink(stream);
weston_debug_stream_v1_send_complete(stream->resource);
}
static void
weston_debug_stream_to_destroy(struct weston_log_subscriber *sub)
{
struct weston_debug_stream *stream = to_weston_debug_stream(sub);
stream_close_on_failure(stream, "debug name removed");
}
static struct weston_debug_stream * static struct weston_debug_stream *
stream_create(struct weston_log_context *log_ctx, const char *name, stream_create(struct weston_log_context *log_ctx, const char *name,
int32_t streamfd, struct wl_resource *stream_resource) int32_t streamfd, struct wl_resource *stream_resource)
{ {
struct weston_debug_stream *stream; struct weston_debug_stream *stream;
struct weston_log_scope *scope; struct weston_log_scope *scope;
struct weston_log_subscription *sub;
stream = zalloc(sizeof *stream); stream = zalloc(sizeof *stream);
if (!stream) if (!stream)
return NULL; return NULL;
stream->fd = streamfd; stream->fd = streamfd;
stream->resource = stream_resource; stream->resource = stream_resource;
stream->base.write = weston_debug_stream_write;
stream->base.destroy = weston_debug_stream_to_destroy;
stream->base.complete = weston_debug_stream_complete;
wl_list_init(&stream->base.subscription_list);
sub = weston_log_subscription_create(&stream->base, name);
scope = get_scope(log_ctx, name); scope = get_scope(log_ctx, name);
if (scope) { if (scope) {
wl_list_insert(&scope->stream_list, &stream->scope_link); weston_log_subscription_add(scope, sub);
if (scope->begin_cb) if (scope->begin_cb)
scope->begin_cb(stream, scope->user_data); scope->begin_cb(scope, scope->user_data);
} else { } else {
wl_list_init(&stream->scope_link);
stream_close_on_failure(stream, stream_close_on_failure(stream,
"Debug stream name '%s' is unknown.", "Debug stream name '%s' is unknown.",
name); name);
@ -316,12 +397,17 @@ static void
stream_destroy(struct wl_resource *stream_resource) stream_destroy(struct wl_resource *stream_resource)
{ {
struct weston_debug_stream *stream; struct weston_debug_stream *stream;
struct weston_log_subscription *sub = NULL;
stream = wl_resource_get_user_data(stream_resource); stream = wl_resource_get_user_data(stream_resource);
if (stream->fd != -1) if (stream->fd != -1)
close(stream->fd); close(stream->fd);
wl_list_remove(&stream->scope_link);
sub = weston_log_subscriber_get_only_subscription(&stream->base);
weston_log_subscription_remove(sub);
weston_log_subscription_destroy(sub);
free(stream); free(stream);
} }
@ -595,7 +681,7 @@ weston_compositor_add_log_scope(struct weston_log_context *log_ctx,
scope->desc = strdup(description); scope->desc = strdup(description);
scope->begin_cb = begin_cb; scope->begin_cb = begin_cb;
scope->user_data = user_data; scope->user_data = user_data;
wl_list_init(&scope->stream_list); wl_list_init(&scope->subscription_list);
if (!scope->name || !scope->desc) { if (!scope->name || !scope->desc) {
weston_log("Error adding debug scope '%s': out of memory.\n", weston_log("Error adding debug scope '%s': out of memory.\n",
@ -623,16 +709,18 @@ weston_compositor_add_log_scope(struct weston_log_context *log_ctx,
WL_EXPORT void WL_EXPORT void
weston_compositor_log_scope_destroy(struct weston_log_scope *scope) weston_compositor_log_scope_destroy(struct weston_log_scope *scope)
{ {
struct weston_debug_stream *stream; struct weston_log_subscription *sub, *sub_tmp;
if (!scope) if (!scope)
return; return;
while (!wl_list_empty(&scope->stream_list)) { wl_list_for_each_safe(sub, sub_tmp, &scope->subscription_list, source_link) {
stream = wl_container_of(scope->stream_list.prev, /* destroy each subscription */
stream, scope_link); if (sub->owner->destroy)
sub->owner->destroy(sub->owner);
stream_close_on_failure(stream, "debug name removed"); weston_log_subscription_remove(sub);
weston_log_subscription_destroy(sub);
} }
wl_list_remove(&scope->compositor_link); wl_list_remove(&scope->compositor_link);
@ -668,115 +756,20 @@ weston_log_scope_is_enabled(struct weston_log_scope *scope)
if (!scope) if (!scope)
return false; return false;
return !wl_list_empty(&scope->stream_list); return !wl_list_empty(&scope->subscription_list);
} }
/** Write data into a specific debug stream
*
* \param stream The debug stream to write into; must not be NULL.
* \param[in] data Pointer to the data to write.
* \param len Number of bytes to write.
*
* Writes the given data (binary verbatim) into the debug stream.
* If \c len is zero or negative, the write is silently dropped.
*
* Writing is continued until all data has been written or
* a write fails. If the write fails due to a signal, it is re-tried.
* Otherwise on failure, the stream is closed and
* \c weston_debug_stream_v1.failure event is sent to the client.
*
* \memberof weston_debug_stream
*/
WL_EXPORT void WL_EXPORT void
weston_debug_stream_write(struct weston_debug_stream *stream, weston_log_scope_complete(struct weston_log_scope *scope)
const char *data, size_t len)
{ {
ssize_t len_ = len; struct weston_log_subscription *sub;
ssize_t ret;
int e;
if (stream->fd == -1) if (!scope)
return; return;
while (len_ > 0) { wl_list_for_each(sub, &scope->subscription_list, source_link)
ret = write(stream->fd, data, len_); if (sub->owner && sub->owner->complete)
e = errno; sub->owner->complete(sub->owner);
if (ret < 0) {
if (e == EINTR)
continue;
stream_close_on_failure(stream,
"Error writing %zd bytes: %s (%d)",
len_, strerror(e), e);
break;
}
len_ -= ret;
data += ret;
}
}
/** Write a formatted string into a specific debug stream (varargs)
*
* \param stream The debug stream to write into.
* \param fmt Printf-style format string.
* \param ap Formatting arguments.
*
* The behavioral details are the same as for weston_debug_stream_write().
*
* \memberof weston_debug_stream
*/
WL_EXPORT void
weston_debug_stream_vprintf(struct weston_debug_stream *stream,
const char *fmt, va_list ap)
{
char *str;
int len;
len = vasprintf(&str, fmt, ap);
if (len >= 0) {
weston_debug_stream_write(stream, str, len);
free(str);
} else {
stream_close_on_failure(stream, "Out of memory");
}
}
/** Write a formatted string into a specific debug stream
*
* \param stream The debug stream to write into.
* \param fmt Printf-style format string and arguments.
*
* The behavioral details are the same as for weston_debug_stream_write().
*
* \memberof weston_debug_stream
*/
WL_EXPORT void
weston_debug_stream_printf(struct weston_debug_stream *stream,
const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
weston_debug_stream_vprintf(stream, fmt, ap);
va_end(ap);
}
/** Close the debug stream and send success event
*
* \param stream The debug stream to close.
*
* Closes the debug stream and sends \c weston_debug_stream_v1.complete
* event to the client. This tells the client the debug information dump
* is complete.
*
* \memberof weston_debug_stream
*/
WL_EXPORT void
weston_debug_stream_complete(struct weston_debug_stream *stream)
{
stream_close_unlink(stream);
weston_debug_stream_v1_send_complete(stream->resource);
} }
/** Write log data for a scope /** Write log data for a scope
@ -788,22 +781,20 @@ weston_debug_stream_complete(struct weston_debug_stream *stream)
* *
* Writes the given data to all subscribed clients' streams. * Writes the given data to all subscribed clients' streams.
* *
* The behavioral details for each stream are the same as for
* weston_debug_stream_write().
*
* \memberof weston_log_scope * \memberof weston_log_scope
*/ */
WL_EXPORT void WL_EXPORT void
weston_log_scope_write(struct weston_log_scope *scope, weston_log_scope_write(struct weston_log_scope *scope,
const char *data, size_t len) const char *data, size_t len)
{ {
struct weston_debug_stream *stream; struct weston_log_subscription *sub;
if (!scope) if (!scope)
return; return;
wl_list_for_each(stream, &scope->stream_list, scope_link) wl_list_for_each(sub, &scope->subscription_list, source_link)
weston_debug_stream_write(stream, data, len); if (sub->owner && sub->owner->write)
sub->owner->write(sub->owner, data, len);
} }
/** Write a formatted string for a scope (varargs) /** Write a formatted string for a scope (varargs)

Loading…
Cancel
Save