3

I am writing a cross-platform library which emulates sockets behaviour, having additional functionality in the between (App->mylib->sockets).

I want it to be the most transparent possible for the programmer, so primitives like select and poll must work accordingly with this lib.

The problem is when data becomes available (for instance) in the real socket, it will have to go through a lot of processing, so if select points to the real socket fd, app will be blocked a lot of time. I want the select/poll to unblock only when data is ready to be consumed (after my lib has done all the processing).

So I came across this eventfd which allows me to do exactly what I want, i.e. to manipule select/poll behaviour on a given fd.

Since I am much more familiarized with Linux environment, I don't know what is the windows equivalent of eventfd. Tried to search but got no luck.

Note: Other approach would be to use another socket connected with the interface, but that seems to be so much overhead. To make a system call with all data just because windows doesn't have (appears so) this functionality.

Or I could just implement my own select, reinventing the wheel. =/

rtruszk
  • 3,902
  • 13
  • 36
  • 53
Leaurus
  • 376
  • 3
  • 13
  • 1
    Windows only provides `select` in WinSock which means it only operates on network sockets and not file descriptors at all. –  Dec 19 '12 at 18:48

2 Answers2

2

There is none. eventfd is a Linux-specific feature -- it's not even available on other UNIXy operating systems, such as BSD and Mac OS X.

2

Yes, but it's ridiculous. You can make a Layered Service Provider (globally installed...) that fiddles with the system's network stack. You get to implement all the WinSock2 functions yourself, and forward most of them to the underlying TCP. This is often used by firewalls or antivirus programs to insert themselves into the stack and see what's going on.

In your case, you'd want to use an ioctl to turn on "special" behaviour for your application. Whenever the app tries to create a socket, it gets forwarded to your function, which in turn opens a real TCP socket (say). Instead of returning that HANDLE though, you use a WinSock function to create ask for a dummy handle from the kernel, and give that to the application instead. You do your stuff in a thread. Then, when the app calls WinSock functions on the dummy handle, they end up in your implementation of read, select, etc. You can decouple select notifications on the dummy handle from those on the actual handle. This lets you do things like, for example, transparently give an app a socket that wraps data each way in encryption, indistinguishably from the original socket. (Almost indistinguishably! You can call some LSP APIs on a handle to find out if there's actually and underlying handle you weren't given.)

Pretty heavy-weight, and monstrous in some ways. But, it's there... Hope that's a useful overview.

Nicholas Wilson
  • 9,435
  • 1
  • 41
  • 80
  • Thanks! That seems the perfect option for Windows, but I am afraid with that approach I almost had to have a completly different implementation for each system (correct me if I am wrong). I think for now I will stick with an AF_UNIX socket when available and TCP socket on localhost for the other systems (e.g. win). – Leaurus Dec 19 '12 at 22:30
  • Good choice. Stay clear of the Windows nonsense where possible. I think your solution is essentially optimal, since if you insist it work with system calls like select, your lib has to hand over an actual fd/socket. – Nicholas Wilson Dec 20 '12 at 01:00