I want prioritization  between reading from many files/pipes. For example I
have one pipe with highest priority and two files with with equal priority.
I want to read pipe and then both files by small chunks. That's the place I
want to use libevent. Is it even possible to read files with libevent?

I tried it like this:
    int file = open(filename, O_RDWR);
    struct event *ev_file_read = event_new(ev_base, file, EV_READ,
read_file, NULL);

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

but it still gives me error:
[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

File is accesible for both read and write.

Any ideas how to do it?

Michal



2011/3/21 Kelly Brock <ke...@inocode.com>

> Hi Michal,
>
>        Libevent's priorities are not likely to do what you want given this
> information.  From my understanding of libevent priorities they only choose
> between existing events and reorder them (basically just the priority queue
> item) but they are tied to a specific fd/event pair such that there is no
> prioritization possible between multiple "read" events.  I.e. there is no
> way to tell libevent that one read or write is more important than another
> if they associated with the same fd.  In fact, I have a feeling that the
> priorities are more intended for event groups and/or timers than they are
> for single fd work.
>
>        As to the high priority traffic, remember that given a single NIC,
> all network traffic is going to be linearized and there is a single
> incoming/outgoing packet stream.  If you are sending a lot of data the
> sendto is likely to start blocking randomly and calling sendto from
> multiple
> threads would not respect priorities.  I think your best bet is still the
> code presented and a very simple send function along the following lines:
>
> while( running )
> {
>  // Note: add a semaphore to the queue to allow pop
>  // to block when there are no messages.  Also add some
>  // form of "exit" message so the thread can be killed cleanly.
>  priority_datagram     msg     =       mStream.pop();
>  uint8_t buffer[ kMaxDatagramSize ];
>  memcpy( buffer, &msg.mStreamId, sizeof( int32_t ) );
>  memcpy( buffer, .... data buffer );
>  sendto( target, buffer, .. size of total packet .. );
> }
>
>        Of course, this still means that there is a certain amount of data
> on the OS buffer which your high priority message will be scheduled to be
> sent after, you have no control over that.  You "could" try adjusting the
> size of the os specific buffer to reduce latency but from my experience
> that
> can cause other problems and waste a lot of bandwidth.
>
>        I personally would still use libevent even in a case like this since
> it does not add any notable latency, is small and takes care of a bunch of
> annoying OS specifics for you.  But don't use the priority system as I
> don't
> believe that it will do anything like what you want.
>
> KB
>
> > Hi Kelly,
> >
> > thanks for your response. My plan is to implement this protocol just as
> > you said. But I don't want to use libevent between Sender and Receiver,
> > since there will be only one socket anyway. Actually I wanted to use it
> > between buffers and sender/receiver as a kind of priority queue.
> >
> > Via this protocol I need to send a lot of data and from time to time
> small
> > chunks of privileged traffic, which has to be delivered immediately.
> > Since libevent supports event's priorities I thought it will be more
> > efficient to invoke Sender's send() method by many threads writing to the
> > FIFO's then using traditional  priority queue + mutexes. I just have no
> > idea if it is the most efficient approach.
> >
> > Michal
> >
> >
> > 2011/3/21 Kelly Brock <ke...@inocode.com>
> >
> >
> >       Hi Michal,
> >
> >              Hopefully this is not too verbose but I'm actually going to
> > be
> >       rewriting a more complicated variation of this problem myself so
> > figured I'd
> >       walk through it in detail as an exercise.
> >
> >              This is really not something you need libevent to do for
> you,
> > in
> >       fact libevent wouldn't support it with udp anyway.  Starting with
> > the
> >       prioritization scheme among the streams, don't bother with anything
> > fancy
> >       since order in this case is just a "suggestion" since you are using
> > udp.
> >       I.e. remember udp can be reordered, some packets can be dropped
> etc.
> >       Anyway, for the sending priority based and stream side of things, I
> > suggest
> >       the following:
> >
> >       struct priority_datagram
> >       {
> >        const bool operator < ( const priority_datagram& rhs ) const
> >        { return mPriority < rhs.mPriority; }
> >
> >        int32_t    mPriority;
> >        uint32_t   mStreamId;
> >        size_t     mLength;
> >        void*      mpPayload;
> >       };
> >       typedef std::priority_queue< priority_datagram >
> > priority_stream_t;
> >
> >       // In some class or whatever.
> >       priotity_stream_t   mStream;
> >       mutex_t             mStreamLock;
> >
> >       // The workers call this to post data packets.
> >       void post( const int32_t priority, const uint32_t streameid, void*
> b
> > )
> >       {
> >        priority_datagram     data    =       {priority, streamed, b};
> >        scoped_lock< mutex_t >  lock( &mStreamLock );
> >        mStream.push( data );
> >       }
> >
> >              That takes care of everything you need to post data to the
> > socket up
> >       to the point where libevent's write callback hits.  Basically you
> > completely
> >       ignore any concept of multiple streams at this level and just build
> > an
> >       outgoing buffer of events, of course by the nature of
> > priority_stream_t,
> >       when libevent calls your callback, you just pop from the buffer and
> >       everything is going to work exactly as you want assuming I've
> > understood
> >       your requirements correctly.
> >
> >              As to the muxing/demuxing.  That's easy; when you get the
> > write
> >       callback for your event, just send the stream id with the payload
> > data in a
> >       single packet.  When reading, pull the stream id and then look up
> > the target
> >       in a hashmap or map whatever to send the data along to the correct
> > stream.
> >       Unless your consumer can't process the data immediately, there is
> no
> > reason
> >       to worry about the priority on this side since udp gets to you
> > whenever it
> >       wants and priority of receipt doesn't make much sense anymore.
> >
> >              Hope this gives you an idea of how to proceed.  Mostly this
> > is not a
> >       problem that libevent solves; it is up to you to do things
> correctly
> > outside
> >       of libevent.
> >
> >       KB
> >
> >
> >       > -----Original Message-----
> >       > From: owner-libevent-us...@freehaven.net [mailto:owner-libevent-
> >       > us...@freehaven.net] On Behalf Of Michal Król
> >       > Sent: Monday, March 21, 2011 5:09 AM
> >       > To: libevent-users@seul.org
> >       > Subject: [Libevent-users] Multiplexing protocol using libevent
> >       >
> >       > Hi,
> >       >
> >       > I'm trying to write multiplexing protocol. Data has to be read
> > from many
> >       > prioritized buffers (which will be fed by many different
> threads),
> > sent as
> >       > a one UDP stream via Network, and then written to many different
> >       > buffers(regarding info from the header).
> >       > To be precise here's an image:
> > http://img861.imageshack.us/i/protocol.png/
> >       >
> >       > Number of buffers can be relatively big (even tens of thousands),
> > but most
> >       > of them will not be used (at least not in the same time). So I
> > need to
> >       > invoke sender, when data arrives to any of these buffers. That's
> > the point
> >       > when I wanted to use libevent. As far as I know to achieve this I
> > need to
> >       > create pipe for every buffer, but I'm afraid it is not the most
> > efficient
> >       > way (especially with such number of pipes). Is there any better
> > way to
> >       > invoke sender?
> >       >
> >       > I need also to do something opposite on the other side of the
> > network (one
> >       > receiver dispatching header, writing to appropriate buffer which
> > will
> >       > invoke appropriate function, but I think solution is the same
> > here.
> >       >
> >       > Anyone has an idea how to efficiently solve this problem?
> >       >
> >       > Thanks in advance
> >       > Michal
> >
> >
> >
> >
> ********************************************************************
> > ***
> >       To unsubscribe, send an e-mail to majord...@freehaven.net with
> >       unsubscribe libevent-users    in the body.
> >
> >
>
>
> ***********************************************************************
> To unsubscribe, send an e-mail to majord...@freehaven.net with
> unsubscribe libevent-users    in the body.
>

Reply via email to