5

I worked with libevent2 for some time, but usually I used it to handle network I/O (using sockets). Now I need to read many different files so I also wanted to use it. I created this code:

int file = open(filename, O_RDONLY);
struct event *ev_file_read = event_new(ev_base, file, EV_READ | EV_PERSIST, read_file, NULL);

if(event_add(ev_file_read, NULL))
        error("adding file event");

Unfortunately it doesn't work. I get this message when trying to add event:

[warn] Epoll ADD(1) on fd 7 failed. Old events were 0; read change was 1 (add); write change was 0 (none): Operation not permitted adding file event: Operation not permitted

The file exists and has rights to read/write.

Anyone has any idea how to handle file IO using libevent? I thought also about bufferred events, but in API there's only function bufferevent_socket_new() which doesn't apply here.

Thanks in advance.

harnen
  • 403
  • 4
  • 12

3 Answers3

7

I needed libevent to read many files regarding priorities. The problem was in epoll not in libevent. Epoll doesn't support regular Unix files.

To solve it I forced libevent not to use epoll:

    struct event_config *cfg = event_config_new();

event_config_avoid_method(cfg, "epoll");

ev_base = event_base_new_with_config(cfg);  
    event_config_free(cfg);

Next method on the preference list was poll, which fully support files just as I wanted to.

Thank you all for answers.

harnen
  • 403
  • 4
  • 12
2

Makes no sense to register regular file descriptors with libevent. File descriptors associated with regular files shall always select true for ready to read, ready to write, and error conditions.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 3
    oh it makes a lot of sense to want such a thing, believe me. and you can have it by adding one level of indirection, see below (or above). – user237419 Mar 28 '11 at 19:54
  • That has little to do with a regular file descriptor. – Maxim Egorushkin Mar 29 '11 at 06:08
  • 2
    directly it has nothing to do, I won't dare to say the opposite; but you can still manage to integrate disk i/o within an existent event loop and this may eliminate some complexity, decrease response times, etc (e.g. the case of a static, readonly http file service) – user237419 Mar 29 '11 at 06:56
1

if you want to do async disk i/o you may want to check the aio_* family (see man (3) aio_read). it's POSIX.1-2001 and available on linux and bsd (at least).

for integrating aio operations with libevent, see libevent aio patch and a related stackoverflow post that mention using signalfd(2) to route the aio signal events to a file descriptor that can be used with various fd event polling implementations (so implicitly with libevent loop).

EDIT: libevent also has signal handling support (totally forgot about that) so you can try and register/handle the aio signals directlry with/from libevent loop. I'd personally go and try the libevent patch first if your development rules allows you to.

Community
  • 1
  • 1
user237419
  • 8,829
  • 4
  • 31
  • 38