console-server: allow separate handler instances

Currently, each handler (socket-handler, tty-handler and log-handler)
provides a statically-allocated instance of a handler, which gets
initialized for a console through the ->init callback.

We have upcoming changes that may create more than one console object,
in which case means we will need multiple instances of each handler
type.

This change splits the handler type from the handler instance; the
former is now struct handler_type, with struct handler being the
instance. Handler modules define a (const) struct handler_type, and
->init() now returns a newly-allocated instance of a handler of that
type.

This allows multiple handlers of each type.

Because the handler instances are allocated by type->init, we now
require both ->init and ->fini to be present on registered handlers.

We no longer need the `bool active` member of the handler, as instances
are always active.

Change-Id: Id97f15bd6445e17786f5883b849de8559c5ea434
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
diff --git a/console-server.h b/console-server.h
index efbfce8..3fd572c 100644
--- a/console-server.h
+++ b/console-server.h
@@ -44,23 +44,35 @@
  * If a handler needs to monitor a separate file descriptor for events, use the
  * poller API, through console_poller_register().
  */
-struct handler {
+struct handler;
+
+struct handler_type {
 	const char *name;
-	int (*init)(struct handler *handler, struct console *console,
-		    struct config *config);
+	struct handler *(*init)(const struct handler_type *type,
+				struct console *console, struct config *config);
 	void (*fini)(struct handler *handler);
 	int (*baudrate)(struct handler *handler, speed_t baudrate);
-	bool active;
+};
+
+struct handler {
+	const struct handler_type *type;
 };
 
 /* NOLINTBEGIN(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
 #define __handler_name(n) __handler_##n
 #define _handler_name(n)  __handler_name(n)
 
+#ifndef __clang__
+#define handler_type_check(h) BUILD_ASSERT_OR_ZERO((h)->init && (h)->fini)
+#else
+/* clang doesn't seem to be able to constify the type ops */
+#define handler_type_check(h) 0
+#endif
+
 #define console_handler_register(h)                                            \
 	static const __attribute__((section("handlers")))                      \
-	__attribute__((used)) struct handler *                                 \
-	_handler_name(__COUNTER__) = h
+	__attribute__((used)) struct handler_type *                            \
+	_handler_name(__COUNTER__) = (h) + handler_type_check(h)
 /* NOLINTEND(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */
 
 int console_data_out(struct console *console, const uint8_t *data, size_t len);