From: Rusty Russell <rusty@rustcorp.com.au>
To: linux-kernel@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>,
Al Viro <viro@zeniv.linux.org.uk>,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 2/6] typesafe_cb: wrappers for typesafe callbacks.
Date: Mon, 21 Apr 2008 09:01:19 +1000 [thread overview]
Message-ID: <200804210901.20229.rusty@rustcorp.com.au> (raw)
In-Reply-To: <200804210900.16242.rusty@rustcorp.com.au>
cast_if_type is clever but annoying to use, so we make some slightly
less annoying wrappers for callback registration.
These allow const pointer-taking functions as well as the normal
non-const ones (volatile variant omitted for simplicity). We also
have a typesafe_cb_preargs() for callbacks which don't just take one
argument.
Here's an example of use:
BEFORE:
void foo_set_callback(int (*callback)(void *), void *arg);
AFTER:
#define foo_set_callback(cb, arg) \
__foo_set_callback(typesafe_cb(int, (cb), (arg)), (arg))
void __foo_set_callback(int (*callback)(void *), void *arg);
o If cb is of form "int cb(typeof(arg))" or "int cb(const typeof(arg))" it
will be cast to form "int cb(void *)".
o Otherwise, if cb is not already of form "int cb(void *)" it will cause a
warning when passed to __foo_set_callback().
o If arg is not a pointer, then handing it to __foo_set_callback() will cause
a warning.
Note: there are at least two possible additions we don't yet need. We
don't cover callbacks which take a volatile pointer, even though that
would be fine, and we don't have a typesafe_cb_postargs().
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
include/linux/kernel.h | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff -r 907c55be656f include/linux/kernel.h
--- a/include/linux/kernel.h Mon Apr 21 06:58:00 2008 +1000
+++ b/include/linux/kernel.h Mon Apr 21 07:04:02 2008 +1000
@@ -436,4 +436,39 @@ struct sysinfo {
#define NUMA_BUILD 0
#endif
+/* If fn is of type ok1 or ok2, cast to desttype */
+#define __typesafe_cb(desttype, fn, ok1, ok2) \
+ cast_if_type(cast_if_type((fn), ok1, desttype), ok2, desttype)
+
+/**
+ * typesafe_cb - cast a callback function if it matches the arg
+ * @rettype: the return type of the callback function
+ * @fn: the callback function to cast
+ * @arg: the (pointer) argument to hand to the callback function.
+ *
+ * If a callback function takes a single argument, this macro does
+ * appropriate casts to a function which takes a single void * argument if the
+ * callback provided matches the @arg (or a const or volatile version).
+ *
+ * It is assumed that @arg is of pointer type: usually @arg is passed
+ * or assigned to a void * elsewhere anyway.
+ */
+#define typesafe_cb(rettype, fn, arg) \
+ __typesafe_cb(rettype (*)(void *), (fn), \
+ rettype (*)(const typeof(arg)), \
+ rettype (*)(typeof(arg)))
+
+/**
+ * typesafe_cb_preargs - cast a callback function if it matches the arg
+ * @rettype: the return type of the callback function
+ * @fn: the callback function to cast
+ * @arg: the (pointer) argument to hand to the callback function.
+ *
+ * This is a version of typesafe_cb() for callbacks that take other arguments
+ * before the @arg.
+ */
+#define typesafe_cb_preargs(rettype, fn, arg, ...) \
+ __typesafe_cb(rettype (*)(__VA_ARGS__, void *), (fn), \
+ rettype (*)(__VA_ARGS__, const typeof(arg)), \
+ rettype (*)(__VA_ARGS__, typeof(arg)))
#endif
next prev parent reply other threads:[~2008-04-20 23:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-20 22:58 [PATCH 0/6] typesafe callbacks Rusty Russell
2008-04-20 23:00 ` [PATCH 1/6] cast_if_type: allow macros functions which take more than one type Rusty Russell
2008-04-20 23:01 ` Rusty Russell [this message]
2008-04-20 23:05 ` [PATCH 3/6] typesafe: Convert stop_machine Rusty Russell
2008-04-20 23:07 ` [PATCH 4/6] typesafe: kthread_create and kthread_run Rusty Russell
2008-04-20 23:09 ` [PATCH 5/6] typesafe: request_irq and devm_request_irq Rusty Russell
2008-04-20 23:10 ` [PATCH 6/6] typesafe: TIMER_INITIALIZER and setup_timer Rusty Russell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200804210901.20229.rusty@rustcorp.com.au \
--to=rusty@rustcorp.com.au \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.