]> git.mikk.net Git - smtpsink/commitdiff
Added inter-module communication "channels" API. Modules can
authorchris mikkelson <chris@mikk.net>
Thu, 15 Apr 2010 21:02:33 +0000 (16:02 -0500)
committerchris mikkelson <chris@mikk.net>
Thu, 15 Apr 2010 21:02:33 +0000 (16:02 -0500)
register callbacks to named channels with ssm_subscribe() and
publish to named channels with ssm_publish().

module_api.c
smtpsink.h

index e0503743194c99f0590f78ae50dec956a1060c54..a2dcd1d33d6316c9d44163ec8e9d762dda15f22e 100644 (file)
@@ -73,3 +73,79 @@ ssm_setpriv(struct smtpsink_module *m, struct conn *c, void *data)
        assert(c->priv_data);
        c->priv_data[m->ssm_module_index] = data;
 }
+
+struct sub {
+       void (*cb)(struct conn *, void *);
+       SLIST_ENTRY(sub) sub_list;
+};
+
+struct channel {
+       const char *name;
+       unsigned np;
+       SLIST_ENTRY(channel) chan_list;
+       SLIST_HEAD(,sub) subscribers;
+};
+
+SLIST_HEAD(,channel) channels = SLIST_HEAD_INITIALIZER(channels);
+
+void
+ssm_subscribe(const char *chan, void (*cb)(struct conn *, void *))
+{
+       struct sub *s = malloc(sizeof(struct sub));
+       struct channel *ch;
+
+       s->cb = cb;
+       SLIST_FOREACH(ch, &channels, chan_list) {
+               if (!strcmp(ch->name, chan)) {
+                       SLIST_INSERT_HEAD(&ch->subscribers, s, sub_list);
+                       return;
+               }
+       }
+       ch = malloc(sizeof(struct channel));
+       ch->name = chan;
+       SLIST_INIT(&ch->subscribers);
+       SLIST_INSERT_HEAD(&ch->subscribers, s, sub_list);
+       SLIST_INSERT_HEAD(&channels, ch, chan_list);
+}
+
+int
+ssm_nproviders(const char *chan)
+{
+       struct channel *ch;
+       SLIST_FOREACH(ch, &channels, chan_list) {
+               if (!strcmp(ch->name, chan))
+                       return ch->np;
+       }
+       return 0;
+}
+
+void
+ssm_provide(const char *chan)
+{
+       struct channel *ch;
+       SLIST_FOREACH(ch, &channels, chan_list) {
+               if (!strcmp(ch->name, chan)) {
+                       ch->np++;
+                       return;
+               }
+       }
+        ch = malloc(sizeof(struct channel));
+        ch->name = chan;
+       ch->np = 1;
+        SLIST_INIT(&ch->subscribers);
+       SLIST_INSERT_HEAD(&channels, ch, chan_list);
+}
+
+void
+ssm_publish(const char *chan, struct conn *c, void *data)
+{
+       struct sub *s;
+       struct channel *ch;
+       SLIST_FOREACH(ch, &channels, chan_list) {
+               if (!strcmp(ch->name, chan)) {
+                       SLIST_FOREACH(s, &ch->subscribers, sub_list) {
+                               s->cb(c, data);
+                       }
+               }
+       }
+}
index a0302f6ffa3db91accff9193f3b2dfe34b4d84e4..11bb6715bd8cdf1aa35d1323dbec5db8bb784ad6 100644 (file)
@@ -88,3 +88,14 @@ struct smtpsink_module {
 
 void *ssm_getpriv(struct smtpsink_module *, struct conn *);
 void ssm_setpriv(struct smtpsink_module *, struct conn *, void *);
+
+/* inter-module communication */
+int ssm_nproviders(const char *);
+void ssm_provide(const char *);
+void ssm_publish(const char *, struct conn *, void *);
+void ssm_subscribe(const char *, void (*)(struct conn *, void *));
+
+struct message_body {
+       char *body;
+       size_t blen;
+};