Hello, I am one who wants waiting on many sockets at once.

At Thu, 14 Jan 2016 18:55:51 +0100, Andres Freund <and...@anarazel.de> wrote in 
<20160114175551.gm10...@awork2.anarazel.de>
> On 2016-01-14 18:14:21 +0100, Andres Freund wrote:
> > On 2016-01-14 12:07:23 -0500, Robert Haas wrote:
> > > > Do we want to provide a backward compatible API for all this? I'm fine
> > > > either way.
> > >
> > > How would that work?
> > 
> > I'm thinking of something like;
> > 
> > int WaitOnLatchSet(LatchEventSet *set, int wakeEvents, long timeout);
> > 
> > int
> > WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,long 
> > timeout)
> > {
> >         LatchEventSet set;
> > 
> >         LatchEventSetInit(&set, latch);
> > 
> >         if (sock != PGINVALID_SOCKET)
> >            LatchEventSetAddSock(&set, sock);
> > 
> >         return WaitOnLatchSet(set, wakeEvents, timeout);
> > }
> > 
> > I think we'll need to continue having wakeEvents and timeout parameters
> > for WaitOnLatchSet, we quite frequently want to wait socket
> > readability/writability, not wait on the socket, or have/not have
> > timeouts.
> 
> Hm. If we really want to support multiple sockets at some point the
> above WaitOnLatchSet signature isn't going to fly, because it won't
> support figuring out which fd the event this triggered on.
> 
> So it seems we'd need to return something like
> struct LatchEvent
> {
>         enum LatchEventType {WL_LATCH_EVENT;WL_TIMEOUT;WL_SOCKET_EVENT; 
> WL_POSTMASTER_EVENT;...} event_type;
>         int mask;
>         pgsocket event_sock;
> };
> 
> that'd also allow to extend this to return multiple events if we want
> that at some point. Alternatively we could add a pgsocket* argument, but
> that doesn't really seem much better.
> 
> Not super happy about the above proposal.

How about allowing registration of a callback for every waiting
socket. The signature of the callback function would be like

enum LATCH_CALLBACK_STATE
 LatchWaitCallback(pgsocket event_sock,
                   enum LatchEventType, int mask?, void *bogus);

It can return, for instance, LCB_CONTINUE, LCB_BREAK or
LCB_IMMEDBREAK, and if any one of them returns LCB_BREAK, it will
break after, maybe, calling all callbacks for fired events.

We could have predefined callbacks for every event which does
only setting a corresponding flag and returns LCB_BREAK.

/* Waiting set has been constructed so far */
if (!WaitOnLatchSet(&set(?))
   errorr()

if (is_sock_readable[sockid]) {} /** is... would be global /
if (is_sock_writable[sockid]) {} /** is... would be global /
/* Any other types of trigger would processes elsewhere */


Although it might be slow if we have an enormous number of
sockets fired at once, I suppose it returns only for a few
sockets on most cases.

I don't see the big picture of the whole latch/signalling
mechanism with this, but callbacks might be usable for signalling
on many sockets.


regards,

-- 
Kyotaro Horiguchi
NTT Open Source Software Center




-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to