14b9f307dSNick Mathewson /*
2e49e2891SNick Mathewson  * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
34b9f307dSNick Mathewson  *
44b9f307dSNick Mathewson  * Redistribution and use in source and binary forms, with or without
54b9f307dSNick Mathewson  * modification, are permitted provided that the following conditions
64b9f307dSNick Mathewson  * are met:
74b9f307dSNick Mathewson  * 1. Redistributions of source code must retain the above copyright
84b9f307dSNick Mathewson  *    notice, this list of conditions and the following disclaimer.
94b9f307dSNick Mathewson  * 2. Redistributions in binary form must reproduce the above copyright
104b9f307dSNick Mathewson  *    notice, this list of conditions and the following disclaimer in the
114b9f307dSNick Mathewson  *    documentation and/or other materials provided with the distribution.
124b9f307dSNick Mathewson  * 3. The name of the author may not be used to endorse or promote products
134b9f307dSNick Mathewson  *    derived from this software without specific prior written permission.
144b9f307dSNick Mathewson  *
154b9f307dSNick Mathewson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
164b9f307dSNick Mathewson  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
174b9f307dSNick Mathewson  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
184b9f307dSNick Mathewson  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
194b9f307dSNick Mathewson  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
204b9f307dSNick Mathewson  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
214b9f307dSNick Mathewson  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
224b9f307dSNick Mathewson  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
234b9f307dSNick Mathewson  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
244b9f307dSNick Mathewson  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
254b9f307dSNick Mathewson  */
263f8c7cd0SNick Mathewson #ifndef CHANGELIST_INTERNAL_H_INCLUDED_
273f8c7cd0SNick Mathewson #define CHANGELIST_INTERNAL_H_INCLUDED_
284b9f307dSNick Mathewson 
294b9f307dSNick Mathewson /*
304b9f307dSNick Mathewson   A "changelist" is a list of all the fd status changes that should be made
314b9f307dSNick Mathewson   between calls to the backend's dispatch function.  There are a few reasons
324b9f307dSNick Mathewson   that a backend would want to queue changes like this rather than processing
334b9f307dSNick Mathewson   them immediately.
344b9f307dSNick Mathewson 
354b9f307dSNick Mathewson     1) Sometimes applications will add and delete the same event more than
364b9f307dSNick Mathewson        once between calls to dispatch.  Processing these changes immediately
374b9f307dSNick Mathewson        is needless, and potentially expensive (especially if we're on a system
384b9f307dSNick Mathewson        that makes one syscall per changed event).
394b9f307dSNick Mathewson 
404b9f307dSNick Mathewson     2) Sometimes we can coalesce multiple changes on the same fd into a single
414b9f307dSNick Mathewson        syscall if we know about them in advance.  For example, epoll can do an
424b9f307dSNick Mathewson        add and a delete at the same time, but only if we have found out about
434b9f307dSNick Mathewson        both of them before we tell epoll.
444b9f307dSNick Mathewson 
454b9f307dSNick Mathewson     3) Sometimes adding an event that we immediately delete can cause
464b9f307dSNick Mathewson        unintended consequences: in kqueue, this makes pending events get
474b9f307dSNick Mathewson        reported spuriously.
484b9f307dSNick Mathewson  */
494b9f307dSNick Mathewson 
50fbe64f21SEvan Jones #include "event2/util.h"
514b9f307dSNick Mathewson 
524b9f307dSNick Mathewson /** Represents a */
534b9f307dSNick Mathewson struct event_change {
544b9f307dSNick Mathewson 	/** The fd or signal whose events are to be changed */
554b9f307dSNick Mathewson 	evutil_socket_t fd;
564b9f307dSNick Mathewson 	/* The events that were enabled on the fd before any of these changes
574b9f307dSNick Mathewson 	   were made.  May include EV_READ or EV_WRITE. */
584b9f307dSNick Mathewson 	short old_events;
594b9f307dSNick Mathewson 
604b9f307dSNick Mathewson 	/* The changes that we want to make in reading and writing on this fd.
614b9f307dSNick Mathewson 	 * If this is a signal, then read_change has EV_CHANGE_SIGNAL set,
624b9f307dSNick Mathewson 	 * and write_change is unused. */
634b9f307dSNick Mathewson 	ev_uint8_t read_change;
644b9f307dSNick Mathewson 	ev_uint8_t write_change;
65*b1b69ac7SDiego Giagio 	ev_uint8_t close_change;
664b9f307dSNick Mathewson };
674b9f307dSNick Mathewson 
684b9f307dSNick Mathewson /* Flags for read_change and write_change. */
694b9f307dSNick Mathewson 
704b9f307dSNick Mathewson /* If set, add the event. */
714b9f307dSNick Mathewson #define EV_CHANGE_ADD     0x01
724b9f307dSNick Mathewson /* If set, delete the event.  Exclusive with EV_CHANGE_ADD */
734b9f307dSNick Mathewson #define EV_CHANGE_DEL     0x02
744b9f307dSNick Mathewson /* If set, this event refers a signal, not an fd. */
754b9f307dSNick Mathewson #define EV_CHANGE_SIGNAL  EV_SIGNAL
764b9f307dSNick Mathewson /* Set for persistent events.  Currently not used. */
774b9f307dSNick Mathewson #define EV_CHANGE_PERSIST EV_PERSIST
784b9f307dSNick Mathewson /* Set for adding edge-triggered events. */
794b9f307dSNick Mathewson #define EV_CHANGE_ET      EV_ET
804b9f307dSNick Mathewson 
814b9f307dSNick Mathewson /* The value of fdinfo_size that a backend should use if it is letting
824b9f307dSNick Mathewson  * changelist handle its add and delete functions. */
834b9f307dSNick Mathewson #define EVENT_CHANGELIST_FDINFO_SIZE sizeof(int)
844b9f307dSNick Mathewson 
854b9f307dSNick Mathewson /** Set up the data fields in a changelist. */
868ac3c4c2SNick Mathewson void event_changelist_init_(struct event_changelist *changelist);
874b9f307dSNick Mathewson /** Remove every change in the changelist, and make corresponding changes
884b9f307dSNick Mathewson  * in the event maps in the base.  This function is generally used right
894b9f307dSNick Mathewson  * after making all the changes in the changelist. */
908ac3c4c2SNick Mathewson void event_changelist_remove_all_(struct event_changelist *changelist,
914b9f307dSNick Mathewson     struct event_base *base);
92c247adc7SNick Mathewson /** Free all memory held in a changelist. */
938ac3c4c2SNick Mathewson void event_changelist_freemem_(struct event_changelist *changelist);
944b9f307dSNick Mathewson 
954b9f307dSNick Mathewson /** Implementation of eventop_add that queues the event in a changelist. */
968ac3c4c2SNick Mathewson int event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, short events,
974b9f307dSNick Mathewson     void *p);
984b9f307dSNick Mathewson /** Implementation of eventop_del that queues the event in a changelist. */
998ac3c4c2SNick Mathewson int event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, short events,
1004b9f307dSNick Mathewson     void *p);
1014b9f307dSNick Mathewson 
1024b9f307dSNick Mathewson #endif
103