I'm writing a method to check if there is new data in a FIFO opened in RDONLY mode. Until now I was using the poll() function but I realized that the kernel on which the code will run doesn't have this function and it implements a subset of the Linux functionality and a subset of the POSIX functionality.
There are alternatives to the poll function?
(In particular, the machine is a BlueGene/Q and the functionalities offered can be found in the Application Development Redbook under the chapter Kernel access.)
Review:
Reading better the redbook I realized that the poll call is included in the kernel. I leave anyway the question because the reply can be useful to someone else.
Check if select(2) is available, it should fit for your needs.
It performs a similar task to poll(2).
Related
I would like to use the PJSIP library to implement a small SIP softphone on an embedded system. Since this embedded system does not offer Linux or support POSIX, I would like to port the PJLIB library only partially, as described here (https://www.pjsip.org/porting.htm#mozTocId30930). The threading function can be deactivated via a macro, but I'm not quite sure yet how I have to set up this new transport function or where exactly it has to be included so that I can also bypass the IOQUEUE implementation and the PJLIB socket abstraction.
On my embedded system (Keil RTX) I can allocate a UDP socket and register a callback which is called on a network event. I also have a send function which I can use to send data packets. Although I have already looked into the stack, I can't find a way to get started.
Has anyone already dared to the partial porting and can give me a brief assistance. Thank you !
See how Symbian port worked (I think it might be removed from recent versions, but it should be still downloadable) - it was also based on non-POSIX sockets. Create your own platform-specific socket file and ioqueue file.
The man page for open() states for O_ASYNC:
This feature is available only for terminals, pseudoterminals,
sockets, and (since Linux 2.6) pipes and FIFOs. See fcntl(2) for
further details.
But I've used linux timers with epoll() successfully and setting O_ASYNC with fcntl() on a timer fd does not return an error. Obviously, no signals are being sent either. My question is, is it possible to get O_ASYNC working with linux timers? Are there any examples online? I know about the POSIX alternative, but was hoping to avoid it.
We can see that F_SETFL calls setfl which calls a fasync function specific to the type of file.
By searching for fasync we can see how async support is implemented in many devices. Seems that it's not too complicated as mostly it only needs the device to store the async registration and send the signal (here is the fasync function implementation for this kind of file).
Going back to setfl we can notice that if the file type's fasync function is null, it just silently succeeds. This could be a bug, or it could be intentional. Let's assume it's a bug.
Now that the bug is in the kernel, there are probably programs relying on it, which would stop working if the bug was fixed. If a program did break and someone complained about it, the fix would get undone so the program would keep working, because Linus doesn't like to break programs. If it doesn't break any programs that actually exist (which is unlikely, in my opinion), it can be fixed.
Another option is to update the documentation.
Another option is to make it actually work.
My question is, is it possible to get O_ASYNC working with linux timers?
It's unlikely (but still possible) that any program is setting O_ASYNC on a timerfd since it doesn't work - so it's unlikely that it will break compatibility. And it looks like it's not terribly complicated to implement, based on the other examples. So, go ahead and write this patch and send it to the mailing list.
If you meant if it's possible to implement on today's kernels, without a patch, the answer is no, it is not. Here is the timerfd ops structure and there is no entry for fasync
Are there any examples online?
Yes, the examples are the source code for all the other kinds of files that support fasync.
I am reading a book about network progamming in C. It is from 2004.
In the example code, author is using select C function to accept multiple connections from the client. Is that function deprecated today?
I see that there are different ways to accept multiplexed I/O like poll and epoll. What are the advantages?
It's not deprecated, and lots of programs rely on it.
It's just not the best tool as it has some limitations:
The number of file descriptors is limited (OS specific, usually possible to increase it with kernel recompiling).
Doesn't scale well (with lots of fds): the whole FD set must be maintained, and re-initialized as select manipulates it.
Feel free to use it if these aren't relevant for you. Otherwise use poll/libevent if you're looking for a cross-platform solution, or in some rare-cases epoll/kqueue for platform specific optimized solutions.
It's not deprecated in its behavior, but its design may have performance issues. For example, linux epoll() documentation states:
API can be used either as an edge-triggered or a level-triggered inter‐
face and scales well to large numbers of watched file descriptors.
Since the efficient alternatives are specific to each operating system, an option better than directly using select() is to use a cross platform multiplexing library (which uses the best implementation available), examples being:
libevent
libev
libuv
If you're developing for a specific operating system, use the recommended implementation for high performance applications.
However, since some people don't like current libraries for I/O multiplexing (due to "being ugly"), select is still a viable alternative.
I've seached such question in google and got different answers.I cann't determine whether posix aio in linux 2.6 support socket file descriptor or not.
if it support tcp socket,does the aiocb.aio_offset=0 relative to the first byte readed from the tcp socket fd?
if it doesn't,does any asynchronous io library in linux support socket fd?
A comment above states that aio does not support sockets. You ask for possible alternatives.
The obvious ones are:
use an event driven programming model, either produced by hand using poll(2) or what have you or via a library like Niels Provos' "libevent"
use threads
I generally prefer the event driven way of doing things, and generally use libevent, which is documented here: http://libevent.org/
Bear in mind, however, that event driven programming is rather heavily different from what you may be used to in program organization. Threads are conceptually similar, although often less efficient when handling large numbers of sockets.
I've been toying around with libevent2, and I've got reading files working, but it blocks. Is there any way to make file reading not block just within libevent. Or, do I need to use another IO library for files and make it pump events that I need.
fd = open("/tmp/hello_world",O_RDONLY);
evbuffer_read(buf,fd,4096);
The O_NONBLOCK flag doesn't work either.
In POSIX disks are considered "fast devices" meaning that they always block (which is why O_NONBLOCK didn't work for you). Only network sockets can be non-blocking.
There is POSIX AIO, but e.g. on Linux that comes with a bunch of restrictions making it unsuitable for general-purpose usage (only for O_DIRECT, I/O must be sector-aligned).
If you want to integrate normal POSIX IO into an asynchronous event loop it seems people resort to thread pools, where the blocking syscalls are executed in the background by one of the worker threads. One example of such a library is libeio
No.
I've yet to see a *nix where you can do non-blocking i/o on regular files without resorting to the more special AIO library (Though for some, e.g. solaris, O_NONBLOCK has an effect if e.g. someone else holds a lock on the file)
Please take a look at libuv, which is used by node.js / io.js: https://github.com/libuv/libuv
It's a good alternative to libeio, because it does perform well on all major operating systems, from Windows to the BSDs, Mac OS X and of course Linux.
It supports I/O completion ports, which makes it a better choice than libeio if you are targeting Windows.
The C code is also very readable and I highly recommend this tutorial: https://nikhilm.github.io/uvbook/