FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Selector support (select/poll/epoll/WaitForMultipleObjects)
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic     Forum Index -> Mango
View previous topic :: View next topic  
Author Message
jcomellas



Joined: 30 Jan 2006
Posts: 22
Location: Buenos Aires, Argentina

PostPosted: Sun Feb 05, 2006 8:20 am    Post subject: Selector support (select/poll/epoll/WaitForMultipleObjects) Reply with quote

I am new to D and I'm trying to add explicit support for select/poll/epoll/WaitForMultipleObjects/etc.. Basically, what I'm doing is adding something similar to Java's NIO Selector to mango.io. The problem I'm having is that I want to be able to "select" on different types of Conduits, not just sockets, but the Conduit classes do not expose their underlying file descriptor/handle. Would it be possible to add that?

Once I'm done with this I want to add an implementation of the Reactor (I/O Demultiplexer) pattern based on this. Something like what the ACE (C++) and the Twisted (Python) frameworks have.
Back to top
View user's profile Send private message
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Sun Feb 05, 2006 7:56 pm    Post subject: Reply with quote

That sounds interesting!

I took a look at doing something like this too, but had a bit of a shock when I saw the state of play on the *nix side (I'm a *nix neophyte). Are you thinking Win32 only, or cross-platform?
Back to top
View user's profile Send private message
jcomellas



Joined: 30 Jan 2006
Posts: 22
Location: Buenos Aires, Argentina

PostPosted: Mon Feb 06, 2006 6:41 am    Post subject: Reply with quote

I was planning on doing this at least for Windows and Linux. The classes will be available for the following platforms, according to the system call used:

select(): Windows and POSIX (practically everywhere)
poll(): POSIX
epoll(): Linux 2.6
WaitForMultipleObjects(): Windows

There are other system calls in other OS's that I haven't used yet and will probably be easy to add (kqueue in FreeBSD, /dev/poll in Solaris, etc.). There are others that work a bit differently and may not be so easy to add using this type of interface (Windows's I/O completion ports, POSIX AIO). Is it wise to add I/O interfaces for platforms in which D is not even supported?
Back to top
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Mon Feb 06, 2006 1:46 pm    Post subject: Reply with quote

Completion ports can be wrapped to make their use fairly generic. Windows also supports a callback method that seems fairly reasonable, as I believe it is nearly the same as completion ports, but it avoids the need for synchronized blocks. As for the rest--I'd say it's worth writing explicit support for the more popular Unix platforms and having select() available as the compatibility option. If someone wants high-performance multiplexing on a non-supported platform they can write the code themselves Smile But Windows and Linux support is probably sufficient for now. The important thing is that the design will adapt well to other methods.
Back to top
View user's profile Send private message
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Mon Feb 06, 2006 1:48 pm    Post subject: Reply with quote

jcomellas wrote:
I was planning on doing this at least for Windows and Linux. The classes will be available for the following platforms, according to the system call used:

select(): Windows and POSIX (practically everywhere)
poll(): POSIX
epoll(): Linux 2.6
WaitForMultipleObjects(): Windows

There are other system calls in other OS's that I haven't used yet and will probably be easy to add (kqueue in FreeBSD, /dev/poll in Solaris, etc.). There are others that work a bit differently and may not be so easy to add using this type of interface (Windows's I/O completion ports, POSIX AIO). Is it wise to add I/O interfaces for platforms in which D is not even supported?

Awesome!

What method signature (for accessing the handles) would be most appropriate? Both Win32 and Linux.
Back to top
View user's profile Send private message
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Mon Feb 06, 2006 1:49 pm    Post subject: Reply with quote

sean wrote:
But Windows and Linux support is probably sufficient for now.

Aye
Back to top
View user's profile Send private message
jcomellas



Joined: 30 Jan 2006
Posts: 22
Location: Buenos Aires, Argentina

PostPosted: Wed Feb 08, 2006 9:56 pm    Post subject: Reply with quote

kris wrote:
What method signature (for accessing the handles) would be most appropriate? Both Win32 and Linux.


Something like handle() or fd() should be enough.


Last edited by jcomellas on Thu Feb 09, 2006 10:13 am; edited 1 time in total
Back to top
View user's profile Send private message
jcomellas



Joined: 30 Jan 2006
Posts: 22
Location: Buenos Aires, Argentina

PostPosted: Thu Feb 09, 2006 10:12 am    Post subject: Reply with quote

jcomellas wrote:
kris wrote:
What method signature (for accessing the handles) would be most appropriate? Both Win32 and Linux.


Something like handle() or fd() should be enough.


Now that I think of it, do you plan to add Conduits for pipes? If so, we'd have to differentiate between the input handle and the output handle.
Back to top
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Thu Feb 09, 2006 10:42 am    Post subject: Reply with quote

Is it even necessary to access the handles directly?
Back to top
View user's profile Send private message
jcomellas



Joined: 30 Jan 2006
Posts: 22
Location: Buenos Aires, Argentina

PostPosted: Mon Feb 13, 2006 7:51 am    Post subject: Reply with quote

sean wrote:
Is it even necessary to access the handles directly?


It's either that or adding a method in the Conduit to register itself to the class that handles the call to select()/poll()/etc. (Selector).

We have several options:

1. The Selector registers the conduit to itself:

Code:
SocketConduit socket;
EpollSelector selector;

selector.register(socket, ISelectionSet.Read);


2. The Selector registers the Conduit's handle:

Code:
SocketConduit socket;
EpollSelector selector;

selector.register(socket.handle(), ISelectionSet.Read);


3. The Conduit registers to the Selector.

Code:
SocketConduit socket;
EpollSelector selector;

socket.register(selector, ISelectionSet.Read);


Which one do you prefer? I'm leaning towards option 1, whereas Java uses option 3.
Back to top
View user's profile Send private message
jcomellas



Joined: 30 Jan 2006
Posts: 22
Location: Buenos Aires, Argentina

PostPosted: Mon Feb 13, 2006 1:57 pm    Post subject: Reply with quote

I have finished the implementation of the first Selector, the EpollSelector for Linux. In order to use this with Mango I need to add some way of getting a Conduit's handle. Kris, do you think you could add that?

Here's a sample of what the usage of a Selector would look like (not compiled yet):

Code:
InternetAddress addr = new InternetAddress("127.0.0.1", 80);
SocketConduit socket;

try
{
    auto ISelector selector = new EpollSelector();
    int timeout = 5000; // 5 seconds
    int eventCount;

    selector.open();
    socket.connect(addr);
    selector.register(socket, ISelectionSet.Read | ISelectionSet.Write);

    eventCount = selector.wait(timeout);
    if (eventCount > 0)
    {
        ISelectionSet selectedSet = selector.selectedSet();

        foreach (Conduit conduit, uint eventMask; selectedSet)
        {
            if (selectedSet.isRead(eventMask))
                writefln("Received a Read event from conduit");
            if (selectedSet.isWrite(eventMask))
                writefln("Received a Write event from conduit");
            if (selectedSet.isError(eventMask))
                writefln("Received an Error event from conduit");
        }
    }
    socket.close();
    selector.close();
}
catch (Exception e)
{
    writefln("Exception caught:\n\n?s", e.toString());
}


What do you think about it?
Back to top
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Mon Feb 13, 2006 4:26 pm    Post subject: Reply with quote

jcomellas wrote:
sean wrote:
Is it even necessary to access the handles directly?


It's either that or adding a method in the Conduit to register itself to the class that handles the call to select()/poll()/etc. (Selector).

We have several options:

1. The Selector registers the conduit to itself:

Code:
SocketConduit socket;
EpollSelector selector;

selector.register(socket, ISelectionSet.Read);


2. The Selector registers the Conduit's handle:

Code:
SocketConduit socket;
EpollSelector selector;

selector.register(socket.handle(), ISelectionSet.Read);


3. The Conduit registers to the Selector.

Code:
SocketConduit socket;
EpollSelector selector;

socket.register(selector, ISelectionSet.Read);


Which one do you prefer? I'm leaning towards option 1, whereas Java uses option 3.

Ah right. In the past I've used option 3 as it allowed me to avoid exposing socket internals or require 'friend' access, but D doesn't have that problem. Option 1 seems the most extensible, so I cast a tenative vote that way even though providing access to the socket handle seems to break encapsulation a bit.
Back to top
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Mon Feb 13, 2006 4:30 pm    Post subject: Reply with quote

jcomellas wrote:
What do you think about it?

Very nice. So to access the data buffer I use conduit? And is there an easy way to know how many bytes are available if a read event occurred? I'll admit I'm still far more familiar with the socket model in general than with how it's modeled in Mango.
Back to top
View user's profile Send private message
jcomellas



Joined: 30 Jan 2006
Posts: 22
Location: Buenos Aires, Argentina

PostPosted: Mon Feb 13, 2006 6:26 pm    Post subject: Reply with quote

sean wrote:
jcomellas wrote:
What do you think about it?

Very nice. So to access the data buffer I use conduit? And is there an easy way to know how many bytes are available if a read event occurred? I'll admit I'm still far more familiar with the socket model in general than with how it's modeled in Mango.


The Selector abstraction only tells you that there is an event waiting to be serviced on a file descriptor. Normally with sockets you should read until the socket is closed or until you've realized that you've already received a whole message or block of data.

I don't think there is a way to see how many bytes are available in the kernel's buffer in a portable manner. IIRC you can do this on Windows, but it won't work on Unix.

The Conduit model is a bit confusing at first but it's very powerful. Certainly, a lot of thought has gone into it. I have to confess that being new to D I still don't have a complete grasp of everything in Mango, but I like very much what I have used so far. It still needs to be tested and debugged a little bit more on Linux, though.
Back to top
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Mon Feb 13, 2006 7:57 pm    Post subject: Reply with quote

jcomellas wrote:
The Selector abstraction only tells you that there is an event waiting to be serviced on a file descriptor. Normally with sockets you should read until the socket is closed or until you've realized that you've already received a whole message or block of data.

Can you explain how this works at a lower level? For example, using IOCP I typically dedicate one or more threads to act as a producer/consumer layer between socket and user code, and allow the thread pool to grow as needed to ensure at least one worker thread is always available (basically, a home grown version of BindIOCPCallback). Is that sort of thing going on behind selector.wait? Or is selector.wait simply a wrapper for GetQueuedCompletionStatus?
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Mango All times are GMT - 6 Hours
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group