[tor-bugs] #18363 [Core Tor/Tor]: Tor could use a publish/subscribe abstraction
Tor Bug Tracker & Wiki
blackhole at torproject.org
Fri May 6 11:13:16 UTC 2016
#18363: Tor could use a publish/subscribe abstraction
-------------------------------------------------+-------------------------
Reporter: nickm | Owner: nickm
Type: enhancement | Status:
Priority: High | needs_revision
Component: Core Tor/Tor | Milestone: Tor:
Severity: Normal | 0.2.9.x-final
Keywords: modularity, tor-modularity, | Version:
TorCoreTeam201605, TorCoreTeam- | Resolution:
postponed-201604 | Actual Points:
Parent ID: | Points: medium
Reviewer: dgoulet | Sponsor:
| SponsorS-can
-------------------------------------------------+-------------------------
Comment (by cypherpunks):
Replying to [comment:14 dgoulet]:
> Replying to [comment:13 cypherpunks]:
> > It's supposed to be an inter-module facility, remember? Think about
it.
>
> It is but that doesn't mean it has to be used inter-module _all_ the
time thus controlling the linkage here is cheap and desirable imo.
Sure, and I conceded as much in the my sentence. But my reminder was also
directed at your item 2. Your feeling is wrong ;).
I'll spell it out, now that I've read the whole thing.
nickm's data structures seem fairly decoupled, I can see a few different
possibilities. Let's see if I understood it correctly. (You correct me
nickm.)
The more straightforward usage would be 1 publisher, n subscribers.
{{{
T-pubsub.h:
#include "pubsub.h
DECLARE_PUBSUB_TOPIC(T)
[...]
T-publishers-private.h:
#include "T-pubsub.h"
DECLARE_NOTIFY_PUBSUB_TOPIC(static, T)
[...]
T-publisher.c:
#include "T-pubsub.h"
#include "T-publisher-private.h"
IMPLEMENT_PUBSUB_TOPIC(static, T)
Use T_notify() and T_clear() here. But maybe also T_subscribe()
and
T_unsubscribe().
[...]
any-T-subscriber.c:
#include "T-publisher.h"
Implement your T_subscriber_fn_t here, or maybe grab a generic one
from
somewhere else (maybe the publisher provides one).
Use T_subscribe() and T_unsubscribe() here.
}}}
But ISTM that n publishers, n subscribers is also possible.
{{{
another-T-publisher.c:
#include "T-pubsub.h"
#include "T-publisher-private.h"
// Note: no IMPLEMENT.
Use T_notify() and T_clear() here. But maybe also T_subscribe()
and
T_unsubscribe().
[...]
}}}
The choice of where to put the definition for `T_event_data_t` and
`T_subscriber_data_t` seems quite open, since the functions in "pubsub.c"
only shuffle pointers around and never dereference them. So it
effectively depends on what the notification handler does with its
arguments (plus maybe style and mental health).
If the T-publisher(s) need to send actual data with the event (the event
is more than just a "signal"), then, logically, T-publisher(s) and
T-subscribers need to have the definition for `T_event_data_t` available.
So it should probably go on the public "T-pubsub.h" header.
If not, then I don't see why you couldn't always pass NULL.
If there's a generic T-notification handler somewhere, then the definition
for `T_subscriber_data_t` should probably be alongside. If instead every
T-subscriber implements his own T-notification handler then the definition
can be in the c unit of each; hell, they could even be all different.
---
Further review comments:
- I don't think you use "tor_queue.h" included in "pubsub.h".
- I don't like the `T_subscriber_fn_t` name (nor the "generic" type name
nor the argument name). A name that conveys "T notification handler", or
similar, would be better IMHO. But T_notification_handler_fn_t is a tiny
bit unwieldy.
- Why does `pubsub_subscriber_fn_t` take a single `void*` argument? Why
not `(void*, void*)`? I see that it's going to be casted anyway, but is
there any reason?
- In `T_call_the_notify_fn_`, maybe document that the reason this function
exists is so that the function pointer can be casted back to the
appropriate type (noting that is not necessary to cast any of the 2 data
pointers, in C).
- `T_subscriber_t` is just used as a type tag, memory is never accessed as
a `T_subscriber_t` (it can't: the type is never defined, only declared),
instead it is always cast to and from `pubsub_subscriber_t` before and
after accessing. Correct?
- In "pubsub.h", there are quite a number of symbols declared outside of
any macro. Why didn't they go inside the implementation macro? Where
else are they needed?
- "Funny" that low priority means high priority ;).
- Did you think about "interesting" interactions? E.g. unsubscribing from
inside a notification handler: is your "smartlist" (more like resizable
array) suitable for work-queue-type usages where you modify the queue as
you traverse it?
--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/18363#comment:15>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online
More information about the tor-bugs
mailing list