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