weston-debug: Introduce weston_log_subscription and weston_log_subscriber objects
Adds a minimalistic API for managing the subscription object. The subscribe functionality will be brought in once we re-organize a bit weston-debug-stream and split it properly. It extends the logging context with a linked list of potential subscription and adds a linked list of subscriptions in the log scope. This patch represents the start of a logging framework for weston. It's being built around weston-debug, with the intent to superseded it, and make weston-debug a client of the framework. Further more the logging framework should replace current logging handler and allow other types of streams to be used. Currently present in libweston under weston-debug we have log scopes, debug streams and a logging context. With this patch, two (internal) objects are being added: the concept of a subscriber and the concept of subscription. The subscription object is a ephemeral object, implicitly managed which is created each time one would want to a subscribe to a scope. The scope will maintain a list of subscriptions and will continue to be explicitly managed. The streams will use the subscriber object as a base class to extend upon. By doing so it allows to customize the stream with specific functions that manipulate the underlaying storage. The subscriber object will require a subscribe function and specific stream functions and like the scope, will be explicitly managed. Signed-off-by: Marius Vlad <marius.vlad@collabora.com> Suggested-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
e48bfc7c0c
commit
e0a858a5f2
|
@ -30,6 +30,8 @@
|
|||
#include "helpers.h"
|
||||
#include <libweston/libweston.h>
|
||||
|
||||
#include "weston-log-internal.h"
|
||||
|
||||
#include "weston-debug-server-protocol.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -41,14 +43,27 @@
|
|||
|
||||
/** Main weston-log context
|
||||
*
|
||||
* One per weston_compositor.
|
||||
* One per weston_compositor. Stores list of scopes created and a list pending
|
||||
* subscriptions.
|
||||
*
|
||||
* \internal
|
||||
* A pending subscription is a subscription to a scope which hasn't been
|
||||
* created. When the scope is finally created the pending subscription will be
|
||||
* removed from the pending subscription list, but not before was added in the
|
||||
* scope's subscription list and that of the subscriber list.
|
||||
*
|
||||
* Pending subscriptions only make sense for other types of streams, other than
|
||||
* those created by weston-debug protocol. In the case of the weston-debug
|
||||
* protocol, the subscription processes is done automatically whenever a client
|
||||
* connects and subscribes to a scope which was previously advertised by the
|
||||
* compositor.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
struct weston_log_context {
|
||||
struct wl_listener compositor_destroy_listener;
|
||||
struct wl_global *global;
|
||||
struct wl_list scope_list; /**< weston_log_scope::compositor_link */
|
||||
struct wl_list pending_subscription_list; /**< weston_log_subscription::source_link */
|
||||
};
|
||||
|
||||
/** weston-log message scope
|
||||
|
@ -64,8 +79,37 @@ struct weston_log_scope {
|
|||
void *user_data;
|
||||
struct wl_list stream_list; /**< weston_debug_stream::scope_link */
|
||||
struct wl_list compositor_link;
|
||||
struct wl_list subscription_list; /**< weston_log_subscription::source_link */
|
||||
};
|
||||
|
||||
/** Ties a subscriber to a scope
|
||||
*
|
||||
* A subscription is created each time we'd want to subscribe to a scope. From
|
||||
* the stream type we can retrieve the subscriber and from the subscriber we
|
||||
* reach each of the streams callbacks. See also weston_log_subscriber object.
|
||||
*
|
||||
* When a subscription has been created we store it in the scope's subscription
|
||||
* list and in the subscriber's subscription list. The subscription might be a
|
||||
* pending subscription until the scope for which there's was a subscribe has
|
||||
* been created. The scope creation will take of looking through the pending
|
||||
* subscription list.
|
||||
*
|
||||
* A subscription can reached from a subscriber subscription list by using the
|
||||
* streams base class.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
struct weston_log_subscription {
|
||||
struct weston_log_subscriber *owner;
|
||||
struct wl_list owner_link; /**< weston_log_subscriber::subscription_list */
|
||||
|
||||
char *scope_name;
|
||||
struct weston_log_scope *source;
|
||||
struct wl_list source_link; /**< weston_log_scope::subscription_list or
|
||||
weston_log_context::pending_subscription_list */
|
||||
};
|
||||
|
||||
|
||||
/** A debug stream created by a client
|
||||
*
|
||||
* A client provides a file descriptor for the server to write debug
|
||||
|
@ -80,6 +124,118 @@ struct weston_debug_stream {
|
|||
struct wl_list scope_link;
|
||||
};
|
||||
|
||||
/** Creates a new subscription using the subscriber by \c owner.
|
||||
*
|
||||
* The subscription created is added to the \c owner subscription list.
|
||||
* Destroying the subscription using weston_log_subscription_destroy() will
|
||||
* remove the link from the subscription list and free storage alloc'ed.
|
||||
*
|
||||
* @param owner the subscriber owner, must be created before creating a
|
||||
* subscription
|
||||
* @param scope_name the scope for which to create this subscription
|
||||
* @returns a weston_log_subscription object in case of success, or NULL
|
||||
* otherwise
|
||||
*
|
||||
* @internal
|
||||
* @sa weston_log_subscription_destroy, weston_log_subscription_remove,
|
||||
* weston_log_subscription_add
|
||||
*/
|
||||
struct weston_log_subscription *
|
||||
weston_log_subscription_create(struct weston_log_subscriber *owner,
|
||||
const char *scope_name)
|
||||
{
|
||||
struct weston_log_subscription *sub;
|
||||
assert(owner);
|
||||
assert(scope_name);
|
||||
|
||||
sub = zalloc(sizeof(*sub));
|
||||
if (!sub)
|
||||
return NULL;
|
||||
|
||||
sub->owner = owner;
|
||||
sub->scope_name = strdup(scope_name);
|
||||
|
||||
wl_list_insert(&sub->owner->subscription_list, &sub->owner_link);
|
||||
return sub;
|
||||
}
|
||||
|
||||
/** Destroys the subscription
|
||||
*
|
||||
* @param sub
|
||||
* @internal
|
||||
*/
|
||||
void
|
||||
weston_log_subscription_destroy(struct weston_log_subscription *sub)
|
||||
{
|
||||
if (sub->owner)
|
||||
wl_list_remove(&sub->owner_link);
|
||||
free(sub->scope_name);
|
||||
free(sub);
|
||||
}
|
||||
|
||||
/** Retrieve a subscription by using the subscriber
|
||||
*
|
||||
* This is useful when trying to find a subscription from the subscriber by
|
||||
* having only access to the stream.
|
||||
*
|
||||
* @param subscriber the subscriber in question
|
||||
* @returns a weston_log_subscription object
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
struct weston_log_subscription *
|
||||
weston_log_subscriber_get_only_subscription(struct weston_log_subscriber *subscriber)
|
||||
{
|
||||
struct weston_log_subscription *sub;
|
||||
/* unlikely, but can happen */
|
||||
if (wl_list_length(&subscriber->subscription_list) == 0)
|
||||
return NULL;
|
||||
|
||||
assert(wl_list_length(&subscriber->subscription_list) == 1);
|
||||
|
||||
return wl_container_of(subscriber->subscription_list.prev,
|
||||
sub, owner_link);
|
||||
}
|
||||
|
||||
/** Adds the subscription \c sub to the subscription list of the
|
||||
* scope.
|
||||
*
|
||||
* This should used when the scope has been created, and the subscription \c
|
||||
* sub has be created before calling this function.
|
||||
*
|
||||
* @param scope the scope
|
||||
* @param sub the subscription, it must be created before, see
|
||||
* weston_log_subscription_create()
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
void
|
||||
weston_log_subscription_add(struct weston_log_scope *scope,
|
||||
struct weston_log_subscription *sub)
|
||||
{
|
||||
assert(scope);
|
||||
assert(sub);
|
||||
/* don't allow subscriptions to have a source already! */
|
||||
assert(!sub->source);
|
||||
|
||||
sub->source = scope;
|
||||
wl_list_insert(&scope->subscription_list, &sub->source_link);
|
||||
}
|
||||
|
||||
/** Removes the subscription from the scope's subscription list
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
void
|
||||
weston_log_subscription_remove(struct weston_log_subscription *sub)
|
||||
{
|
||||
assert(sub);
|
||||
if (sub->source)
|
||||
wl_list_remove(&sub->source_link);
|
||||
sub->source = NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct weston_log_scope *
|
||||
get_scope(struct weston_log_context *log_ctx, const char *name)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright © 2019 Collabora Ltd
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef WESTON_LOG_INTERNAL_H
|
||||
#define WESTON_LOG_INTERNAL_H
|
||||
|
||||
#include "wayland-util.h"
|
||||
|
||||
/** Subscriber allows each type of stream to customize or to provide its own
|
||||
* methods to manipulate the underlying storage. It follows also an
|
||||
* object-oriented approach, contains the ops callbacks and a list of
|
||||
* subcriptions of type weston_log_subscription. Each subscription created will
|
||||
* be both added to this subscription list and that of the weston_log_scope.
|
||||
*
|
||||
* A kind of stream can inherit the subscriber class and provide its own callbacks:
|
||||
* @code
|
||||
* struct weston_log_data_stream {
|
||||
* struct weston_log_subscriber base;
|
||||
* struct weston_data_stream opaque;
|
||||
* };
|
||||
* @endcode
|
||||
*
|
||||
* Passing the base class will require container retrieval type of methods
|
||||
* to be allowed to reach the opaque type (i.e., container_of()).
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
*/
|
||||
struct weston_log_subscriber {
|
||||
/** write the data pointed by @param data */
|
||||
void (*write)(struct weston_log_subscriber *sub, const char *data, size_t len);
|
||||
/** For the type of streams that required additional destroy operation
|
||||
* for destroying the stream */
|
||||
void (*destroy)(struct weston_log_subscriber *sub);
|
||||
/** For the type of streams that can inform the 'consumer' part that
|
||||
* write operation has been terminated/finished and should close the
|
||||
* stream.
|
||||
*/
|
||||
void (*complete)(struct weston_log_subscriber *sub);
|
||||
struct wl_list subscription_list; /**< weston_log_subscription::owner_link */
|
||||
};
|
||||
|
||||
struct weston_log_subscription *
|
||||
weston_log_subscription_create(struct weston_log_subscriber *owner,
|
||||
const char *scope_name);
|
||||
|
||||
void
|
||||
weston_log_subscription_destroy(struct weston_log_subscription *sub);
|
||||
|
||||
struct weston_log_subscription *
|
||||
weston_log_subscriber_get_only_subscription(struct weston_log_subscriber *subscriber);
|
||||
|
||||
void
|
||||
weston_log_subscription_add(struct weston_log_scope *scope,
|
||||
struct weston_log_subscription *sub);
|
||||
void
|
||||
weston_log_subscription_remove(struct weston_log_subscription *sub);
|
||||
|
||||
#endif /* WESTON_LOG_INTERNAL_H */
|
Loading…
Reference in New Issue