1*e985b929SDavid van Moolenbroek /* $NetBSD: buffer_iocp.c,v 1.1.1.1 2013/04/11 16:43:25 christos Exp $ */
2*e985b929SDavid van Moolenbroek /*
3*e985b929SDavid van Moolenbroek * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
4*e985b929SDavid van Moolenbroek *
5*e985b929SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
6*e985b929SDavid van Moolenbroek * modification, are permitted provided that the following conditions
7*e985b929SDavid van Moolenbroek * are met:
8*e985b929SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
9*e985b929SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
10*e985b929SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
11*e985b929SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
12*e985b929SDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
13*e985b929SDavid van Moolenbroek * 3. The name of the author may not be used to endorse or promote products
14*e985b929SDavid van Moolenbroek * derived from this software without specific prior written permission.
15*e985b929SDavid van Moolenbroek *
16*e985b929SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*e985b929SDavid van Moolenbroek * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*e985b929SDavid van Moolenbroek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*e985b929SDavid van Moolenbroek * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*e985b929SDavid van Moolenbroek * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*e985b929SDavid van Moolenbroek * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*e985b929SDavid van Moolenbroek * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*e985b929SDavid van Moolenbroek * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*e985b929SDavid van Moolenbroek * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*e985b929SDavid van Moolenbroek * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*e985b929SDavid van Moolenbroek */
27*e985b929SDavid van Moolenbroek
28*e985b929SDavid van Moolenbroek /**
29*e985b929SDavid van Moolenbroek @file buffer_iocp.c
30*e985b929SDavid van Moolenbroek
31*e985b929SDavid van Moolenbroek This module implements overlapped read and write functions for evbuffer
32*e985b929SDavid van Moolenbroek objects on Windows.
33*e985b929SDavid van Moolenbroek */
34*e985b929SDavid van Moolenbroek
35*e985b929SDavid van Moolenbroek #include "event2/buffer.h"
36*e985b929SDavid van Moolenbroek #include "event2/buffer_compat.h"
37*e985b929SDavid van Moolenbroek #include "event2/util.h"
38*e985b929SDavid van Moolenbroek #include "event2/thread.h"
39*e985b929SDavid van Moolenbroek #include "event2/event-config.h"
40*e985b929SDavid van Moolenbroek #include <sys/cdefs.h>
41*e985b929SDavid van Moolenbroek __RCSID("$NetBSD: buffer_iocp.c,v 1.1.1.1 2013/04/11 16:43:25 christos Exp $");
42*e985b929SDavid van Moolenbroek #include "util-internal.h"
43*e985b929SDavid van Moolenbroek #include "evthread-internal.h"
44*e985b929SDavid van Moolenbroek #include "evbuffer-internal.h"
45*e985b929SDavid van Moolenbroek #include "iocp-internal.h"
46*e985b929SDavid van Moolenbroek #include "mm-internal.h"
47*e985b929SDavid van Moolenbroek
48*e985b929SDavid van Moolenbroek #include <winsock2.h>
49*e985b929SDavid van Moolenbroek #include <windows.h>
50*e985b929SDavid van Moolenbroek #include <stdio.h>
51*e985b929SDavid van Moolenbroek
52*e985b929SDavid van Moolenbroek #define MAX_WSABUFS 16
53*e985b929SDavid van Moolenbroek
54*e985b929SDavid van Moolenbroek /** An evbuffer that can handle overlapped IO. */
55*e985b929SDavid van Moolenbroek struct evbuffer_overlapped {
56*e985b929SDavid van Moolenbroek struct evbuffer buffer;
57*e985b929SDavid van Moolenbroek /** The socket that we're doing overlapped IO on. */
58*e985b929SDavid van Moolenbroek evutil_socket_t fd;
59*e985b929SDavid van Moolenbroek
60*e985b929SDavid van Moolenbroek /** pending I/O type */
61*e985b929SDavid van Moolenbroek unsigned read_in_progress : 1;
62*e985b929SDavid van Moolenbroek unsigned write_in_progress : 1;
63*e985b929SDavid van Moolenbroek
64*e985b929SDavid van Moolenbroek /** The first pinned chain in the buffer. */
65*e985b929SDavid van Moolenbroek struct evbuffer_chain *first_pinned;
66*e985b929SDavid van Moolenbroek
67*e985b929SDavid van Moolenbroek /** How many chains are pinned; how many of the fields in buffers
68*e985b929SDavid van Moolenbroek * are we using. */
69*e985b929SDavid van Moolenbroek int n_buffers;
70*e985b929SDavid van Moolenbroek WSABUF buffers[MAX_WSABUFS];
71*e985b929SDavid van Moolenbroek };
72*e985b929SDavid van Moolenbroek
73*e985b929SDavid van Moolenbroek /** Given an evbuffer, return the correponding evbuffer structure, or NULL if
74*e985b929SDavid van Moolenbroek * the evbuffer isn't overlapped. */
75*e985b929SDavid van Moolenbroek static inline struct evbuffer_overlapped *
upcast_evbuffer(struct evbuffer * buf)76*e985b929SDavid van Moolenbroek upcast_evbuffer(struct evbuffer *buf)
77*e985b929SDavid van Moolenbroek {
78*e985b929SDavid van Moolenbroek if (!buf || !buf->is_overlapped)
79*e985b929SDavid van Moolenbroek return NULL;
80*e985b929SDavid van Moolenbroek return EVUTIL_UPCAST(buf, struct evbuffer_overlapped, buffer);
81*e985b929SDavid van Moolenbroek }
82*e985b929SDavid van Moolenbroek
83*e985b929SDavid van Moolenbroek /** Unpin all the chains noted as pinned in 'eo'. */
84*e985b929SDavid van Moolenbroek static void
pin_release(struct evbuffer_overlapped * eo,unsigned flag)85*e985b929SDavid van Moolenbroek pin_release(struct evbuffer_overlapped *eo, unsigned flag)
86*e985b929SDavid van Moolenbroek {
87*e985b929SDavid van Moolenbroek int i;
88*e985b929SDavid van Moolenbroek struct evbuffer_chain *next, *chain = eo->first_pinned;
89*e985b929SDavid van Moolenbroek
90*e985b929SDavid van Moolenbroek for (i = 0; i < eo->n_buffers; ++i) {
91*e985b929SDavid van Moolenbroek EVUTIL_ASSERT(chain);
92*e985b929SDavid van Moolenbroek next = chain->next;
93*e985b929SDavid van Moolenbroek _evbuffer_chain_unpin(chain, flag);
94*e985b929SDavid van Moolenbroek chain = next;
95*e985b929SDavid van Moolenbroek }
96*e985b929SDavid van Moolenbroek }
97*e985b929SDavid van Moolenbroek
98*e985b929SDavid van Moolenbroek void
evbuffer_commit_read(struct evbuffer * evbuf,ev_ssize_t nBytes)99*e985b929SDavid van Moolenbroek evbuffer_commit_read(struct evbuffer *evbuf, ev_ssize_t nBytes)
100*e985b929SDavid van Moolenbroek {
101*e985b929SDavid van Moolenbroek struct evbuffer_overlapped *buf = upcast_evbuffer(evbuf);
102*e985b929SDavid van Moolenbroek struct evbuffer_chain **chainp;
103*e985b929SDavid van Moolenbroek size_t remaining, len;
104*e985b929SDavid van Moolenbroek unsigned i;
105*e985b929SDavid van Moolenbroek
106*e985b929SDavid van Moolenbroek EVBUFFER_LOCK(evbuf);
107*e985b929SDavid van Moolenbroek EVUTIL_ASSERT(buf->read_in_progress && !buf->write_in_progress);
108*e985b929SDavid van Moolenbroek EVUTIL_ASSERT(nBytes >= 0); /* XXXX Can this be false? */
109*e985b929SDavid van Moolenbroek
110*e985b929SDavid van Moolenbroek evbuffer_unfreeze(evbuf, 0);
111*e985b929SDavid van Moolenbroek
112*e985b929SDavid van Moolenbroek chainp = evbuf->last_with_datap;
113*e985b929SDavid van Moolenbroek if (!((*chainp)->flags & EVBUFFER_MEM_PINNED_R))
114*e985b929SDavid van Moolenbroek chainp = &(*chainp)->next;
115*e985b929SDavid van Moolenbroek remaining = nBytes;
116*e985b929SDavid van Moolenbroek for (i = 0; remaining > 0 && i < (unsigned)buf->n_buffers; ++i) {
117*e985b929SDavid van Moolenbroek EVUTIL_ASSERT(*chainp);
118*e985b929SDavid van Moolenbroek len = buf->buffers[i].len;
119*e985b929SDavid van Moolenbroek if (remaining < len)
120*e985b929SDavid van Moolenbroek len = remaining;
121*e985b929SDavid van Moolenbroek (*chainp)->off += len;
122*e985b929SDavid van Moolenbroek evbuf->last_with_datap = chainp;
123*e985b929SDavid van Moolenbroek remaining -= len;
124*e985b929SDavid van Moolenbroek chainp = &(*chainp)->next;
125*e985b929SDavid van Moolenbroek }
126*e985b929SDavid van Moolenbroek
127*e985b929SDavid van Moolenbroek pin_release(buf, EVBUFFER_MEM_PINNED_R);
128*e985b929SDavid van Moolenbroek
129*e985b929SDavid van Moolenbroek buf->read_in_progress = 0;
130*e985b929SDavid van Moolenbroek
131*e985b929SDavid van Moolenbroek evbuf->total_len += nBytes;
132*e985b929SDavid van Moolenbroek evbuf->n_add_for_cb += nBytes;
133*e985b929SDavid van Moolenbroek
134*e985b929SDavid van Moolenbroek evbuffer_invoke_callbacks(evbuf);
135*e985b929SDavid van Moolenbroek
136*e985b929SDavid van Moolenbroek _evbuffer_decref_and_unlock(evbuf);
137*e985b929SDavid van Moolenbroek }
138*e985b929SDavid van Moolenbroek
139*e985b929SDavid van Moolenbroek void
evbuffer_commit_write(struct evbuffer * evbuf,ev_ssize_t nBytes)140*e985b929SDavid van Moolenbroek evbuffer_commit_write(struct evbuffer *evbuf, ev_ssize_t nBytes)
141*e985b929SDavid van Moolenbroek {
142*e985b929SDavid van Moolenbroek struct evbuffer_overlapped *buf = upcast_evbuffer(evbuf);
143*e985b929SDavid van Moolenbroek
144*e985b929SDavid van Moolenbroek EVBUFFER_LOCK(evbuf);
145*e985b929SDavid van Moolenbroek EVUTIL_ASSERT(buf->write_in_progress && !buf->read_in_progress);
146*e985b929SDavid van Moolenbroek evbuffer_unfreeze(evbuf, 1);
147*e985b929SDavid van Moolenbroek evbuffer_drain(evbuf, nBytes);
148*e985b929SDavid van Moolenbroek pin_release(buf,EVBUFFER_MEM_PINNED_W);
149*e985b929SDavid van Moolenbroek buf->write_in_progress = 0;
150*e985b929SDavid van Moolenbroek _evbuffer_decref_and_unlock(evbuf);
151*e985b929SDavid van Moolenbroek }
152*e985b929SDavid van Moolenbroek
153*e985b929SDavid van Moolenbroek struct evbuffer *
evbuffer_overlapped_new(evutil_socket_t fd)154*e985b929SDavid van Moolenbroek evbuffer_overlapped_new(evutil_socket_t fd)
155*e985b929SDavid van Moolenbroek {
156*e985b929SDavid van Moolenbroek struct evbuffer_overlapped *evo;
157*e985b929SDavid van Moolenbroek
158*e985b929SDavid van Moolenbroek evo = mm_calloc(1, sizeof(struct evbuffer_overlapped));
159*e985b929SDavid van Moolenbroek if (!evo)
160*e985b929SDavid van Moolenbroek return NULL;
161*e985b929SDavid van Moolenbroek
162*e985b929SDavid van Moolenbroek TAILQ_INIT(&evo->buffer.callbacks);
163*e985b929SDavid van Moolenbroek evo->buffer.refcnt = 1;
164*e985b929SDavid van Moolenbroek evo->buffer.last_with_datap = &evo->buffer.first;
165*e985b929SDavid van Moolenbroek
166*e985b929SDavid van Moolenbroek evo->buffer.is_overlapped = 1;
167*e985b929SDavid van Moolenbroek evo->fd = fd;
168*e985b929SDavid van Moolenbroek
169*e985b929SDavid van Moolenbroek return &evo->buffer;
170*e985b929SDavid van Moolenbroek }
171*e985b929SDavid van Moolenbroek
172*e985b929SDavid van Moolenbroek int
evbuffer_launch_write(struct evbuffer * buf,ev_ssize_t at_most,struct event_overlapped * ol)173*e985b929SDavid van Moolenbroek evbuffer_launch_write(struct evbuffer *buf, ev_ssize_t at_most,
174*e985b929SDavid van Moolenbroek struct event_overlapped *ol)
175*e985b929SDavid van Moolenbroek {
176*e985b929SDavid van Moolenbroek struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf);
177*e985b929SDavid van Moolenbroek int r = -1;
178*e985b929SDavid van Moolenbroek int i;
179*e985b929SDavid van Moolenbroek struct evbuffer_chain *chain;
180*e985b929SDavid van Moolenbroek DWORD bytesSent;
181*e985b929SDavid van Moolenbroek
182*e985b929SDavid van Moolenbroek if (!buf) {
183*e985b929SDavid van Moolenbroek /* No buffer, or it isn't overlapped */
184*e985b929SDavid van Moolenbroek return -1;
185*e985b929SDavid van Moolenbroek }
186*e985b929SDavid van Moolenbroek
187*e985b929SDavid van Moolenbroek EVBUFFER_LOCK(buf);
188*e985b929SDavid van Moolenbroek EVUTIL_ASSERT(!buf_o->read_in_progress);
189*e985b929SDavid van Moolenbroek if (buf->freeze_start || buf_o->write_in_progress)
190*e985b929SDavid van Moolenbroek goto done;
191*e985b929SDavid van Moolenbroek if (!buf->total_len) {
192*e985b929SDavid van Moolenbroek /* Nothing to write */
193*e985b929SDavid van Moolenbroek r = 0;
194*e985b929SDavid van Moolenbroek goto done;
195*e985b929SDavid van Moolenbroek } else if (at_most < 0 || (size_t)at_most > buf->total_len) {
196*e985b929SDavid van Moolenbroek at_most = buf->total_len;
197*e985b929SDavid van Moolenbroek }
198*e985b929SDavid van Moolenbroek evbuffer_freeze(buf, 1);
199*e985b929SDavid van Moolenbroek
200*e985b929SDavid van Moolenbroek buf_o->first_pinned = NULL;
201*e985b929SDavid van Moolenbroek buf_o->n_buffers = 0;
202*e985b929SDavid van Moolenbroek memset(buf_o->buffers, 0, sizeof(buf_o->buffers));
203*e985b929SDavid van Moolenbroek
204*e985b929SDavid van Moolenbroek chain = buf_o->first_pinned = buf->first;
205*e985b929SDavid van Moolenbroek
206*e985b929SDavid van Moolenbroek for (i=0; i < MAX_WSABUFS && chain; ++i, chain=chain->next) {
207*e985b929SDavid van Moolenbroek WSABUF *b = &buf_o->buffers[i];
208*e985b929SDavid van Moolenbroek b->buf = (char*)( chain->buffer + chain->misalign );
209*e985b929SDavid van Moolenbroek _evbuffer_chain_pin(chain, EVBUFFER_MEM_PINNED_W);
210*e985b929SDavid van Moolenbroek
211*e985b929SDavid van Moolenbroek if ((size_t)at_most > chain->off) {
212*e985b929SDavid van Moolenbroek /* XXXX Cast is safe for now, since win32 has no
213*e985b929SDavid van Moolenbroek mmaped chains. But later, we need to have this
214*e985b929SDavid van Moolenbroek add more WSAbufs if chain->off is greater than
215*e985b929SDavid van Moolenbroek ULONG_MAX */
216*e985b929SDavid van Moolenbroek b->len = (unsigned long)chain->off;
217*e985b929SDavid van Moolenbroek at_most -= chain->off;
218*e985b929SDavid van Moolenbroek } else {
219*e985b929SDavid van Moolenbroek b->len = (unsigned long)at_most;
220*e985b929SDavid van Moolenbroek ++i;
221*e985b929SDavid van Moolenbroek break;
222*e985b929SDavid van Moolenbroek }
223*e985b929SDavid van Moolenbroek }
224*e985b929SDavid van Moolenbroek
225*e985b929SDavid van Moolenbroek buf_o->n_buffers = i;
226*e985b929SDavid van Moolenbroek _evbuffer_incref(buf);
227*e985b929SDavid van Moolenbroek if (WSASend(buf_o->fd, buf_o->buffers, i, &bytesSent, 0,
228*e985b929SDavid van Moolenbroek &ol->overlapped, NULL)) {
229*e985b929SDavid van Moolenbroek int error = WSAGetLastError();
230*e985b929SDavid van Moolenbroek if (error != WSA_IO_PENDING) {
231*e985b929SDavid van Moolenbroek /* An actual error. */
232*e985b929SDavid van Moolenbroek pin_release(buf_o, EVBUFFER_MEM_PINNED_W);
233*e985b929SDavid van Moolenbroek evbuffer_unfreeze(buf, 1);
234*e985b929SDavid van Moolenbroek evbuffer_free(buf); /* decref */
235*e985b929SDavid van Moolenbroek goto done;
236*e985b929SDavid van Moolenbroek }
237*e985b929SDavid van Moolenbroek }
238*e985b929SDavid van Moolenbroek
239*e985b929SDavid van Moolenbroek buf_o->write_in_progress = 1;
240*e985b929SDavid van Moolenbroek r = 0;
241*e985b929SDavid van Moolenbroek done:
242*e985b929SDavid van Moolenbroek EVBUFFER_UNLOCK(buf);
243*e985b929SDavid van Moolenbroek return r;
244*e985b929SDavid van Moolenbroek }
245*e985b929SDavid van Moolenbroek
246*e985b929SDavid van Moolenbroek int
evbuffer_launch_read(struct evbuffer * buf,size_t at_most,struct event_overlapped * ol)247*e985b929SDavid van Moolenbroek evbuffer_launch_read(struct evbuffer *buf, size_t at_most,
248*e985b929SDavid van Moolenbroek struct event_overlapped *ol)
249*e985b929SDavid van Moolenbroek {
250*e985b929SDavid van Moolenbroek struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf);
251*e985b929SDavid van Moolenbroek int r = -1, i;
252*e985b929SDavid van Moolenbroek int nvecs;
253*e985b929SDavid van Moolenbroek int npin=0;
254*e985b929SDavid van Moolenbroek struct evbuffer_chain *chain=NULL, **chainp;
255*e985b929SDavid van Moolenbroek DWORD bytesRead;
256*e985b929SDavid van Moolenbroek DWORD flags = 0;
257*e985b929SDavid van Moolenbroek struct evbuffer_iovec vecs[MAX_WSABUFS];
258*e985b929SDavid van Moolenbroek
259*e985b929SDavid van Moolenbroek if (!buf_o)
260*e985b929SDavid van Moolenbroek return -1;
261*e985b929SDavid van Moolenbroek EVBUFFER_LOCK(buf);
262*e985b929SDavid van Moolenbroek EVUTIL_ASSERT(!buf_o->write_in_progress);
263*e985b929SDavid van Moolenbroek if (buf->freeze_end || buf_o->read_in_progress)
264*e985b929SDavid van Moolenbroek goto done;
265*e985b929SDavid van Moolenbroek
266*e985b929SDavid van Moolenbroek buf_o->first_pinned = NULL;
267*e985b929SDavid van Moolenbroek buf_o->n_buffers = 0;
268*e985b929SDavid van Moolenbroek memset(buf_o->buffers, 0, sizeof(buf_o->buffers));
269*e985b929SDavid van Moolenbroek
270*e985b929SDavid van Moolenbroek if (_evbuffer_expand_fast(buf, at_most, MAX_WSABUFS) == -1)
271*e985b929SDavid van Moolenbroek goto done;
272*e985b929SDavid van Moolenbroek evbuffer_freeze(buf, 0);
273*e985b929SDavid van Moolenbroek
274*e985b929SDavid van Moolenbroek nvecs = _evbuffer_read_setup_vecs(buf, at_most,
275*e985b929SDavid van Moolenbroek vecs, MAX_WSABUFS, &chainp, 1);
276*e985b929SDavid van Moolenbroek for (i=0;i<nvecs;++i) {
277*e985b929SDavid van Moolenbroek WSABUF_FROM_EVBUFFER_IOV(
278*e985b929SDavid van Moolenbroek &buf_o->buffers[i],
279*e985b929SDavid van Moolenbroek &vecs[i]);
280*e985b929SDavid van Moolenbroek }
281*e985b929SDavid van Moolenbroek
282*e985b929SDavid van Moolenbroek buf_o->n_buffers = nvecs;
283*e985b929SDavid van Moolenbroek buf_o->first_pinned = chain = *chainp;
284*e985b929SDavid van Moolenbroek
285*e985b929SDavid van Moolenbroek npin=0;
286*e985b929SDavid van Moolenbroek for ( ; chain; chain = chain->next) {
287*e985b929SDavid van Moolenbroek _evbuffer_chain_pin(chain, EVBUFFER_MEM_PINNED_R);
288*e985b929SDavid van Moolenbroek ++npin;
289*e985b929SDavid van Moolenbroek }
290*e985b929SDavid van Moolenbroek EVUTIL_ASSERT(npin == nvecs);
291*e985b929SDavid van Moolenbroek
292*e985b929SDavid van Moolenbroek _evbuffer_incref(buf);
293*e985b929SDavid van Moolenbroek if (WSARecv(buf_o->fd, buf_o->buffers, nvecs, &bytesRead, &flags,
294*e985b929SDavid van Moolenbroek &ol->overlapped, NULL)) {
295*e985b929SDavid van Moolenbroek int error = WSAGetLastError();
296*e985b929SDavid van Moolenbroek if (error != WSA_IO_PENDING) {
297*e985b929SDavid van Moolenbroek /* An actual error. */
298*e985b929SDavid van Moolenbroek pin_release(buf_o, EVBUFFER_MEM_PINNED_R);
299*e985b929SDavid van Moolenbroek evbuffer_unfreeze(buf, 0);
300*e985b929SDavid van Moolenbroek evbuffer_free(buf); /* decref */
301*e985b929SDavid van Moolenbroek goto done;
302*e985b929SDavid van Moolenbroek }
303*e985b929SDavid van Moolenbroek }
304*e985b929SDavid van Moolenbroek
305*e985b929SDavid van Moolenbroek buf_o->read_in_progress = 1;
306*e985b929SDavid van Moolenbroek r = 0;
307*e985b929SDavid van Moolenbroek done:
308*e985b929SDavid van Moolenbroek EVBUFFER_UNLOCK(buf);
309*e985b929SDavid van Moolenbroek return r;
310*e985b929SDavid van Moolenbroek }
311*e985b929SDavid van Moolenbroek
312*e985b929SDavid van Moolenbroek evutil_socket_t
_evbuffer_overlapped_get_fd(struct evbuffer * buf)313*e985b929SDavid van Moolenbroek _evbuffer_overlapped_get_fd(struct evbuffer *buf)
314*e985b929SDavid van Moolenbroek {
315*e985b929SDavid van Moolenbroek struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf);
316*e985b929SDavid van Moolenbroek return buf_o ? buf_o->fd : -1;
317*e985b929SDavid van Moolenbroek }
318*e985b929SDavid van Moolenbroek
319*e985b929SDavid van Moolenbroek void
_evbuffer_overlapped_set_fd(struct evbuffer * buf,evutil_socket_t fd)320*e985b929SDavid van Moolenbroek _evbuffer_overlapped_set_fd(struct evbuffer *buf, evutil_socket_t fd)
321*e985b929SDavid van Moolenbroek {
322*e985b929SDavid van Moolenbroek struct evbuffer_overlapped *buf_o = upcast_evbuffer(buf);
323*e985b929SDavid van Moolenbroek EVBUFFER_LOCK(buf);
324*e985b929SDavid van Moolenbroek /* XXX is this right?, should it cancel current I/O operations? */
325*e985b929SDavid van Moolenbroek if (buf_o)
326*e985b929SDavid van Moolenbroek buf_o->fd = fd;
327*e985b929SDavid van Moolenbroek EVBUFFER_UNLOCK(buf);
328*e985b929SDavid van Moolenbroek }
329