blob: a3875ce16c4e45a69e0da09b24cb0da98139485f [file] [log] [blame]
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +01001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, Google Inc.
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +01004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Craig Tiller9a4dddd2016-03-25 17:08:13 -070034#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H
35#define GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +010036
Craig Tillerae65f1a2015-07-01 11:23:59 -070037#include <grpc/support/port_platform.h>
Craig Tiller684d8f62015-07-01 11:31:48 -070038#include <winsock2.h>
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +010039
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +010040#include <grpc/support/atm.h>
Craig Tillerf40df232016-03-25 13:38:14 -070041#include <grpc/support/sync.h>
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +010042
Craig Tiller9533d042016-03-25 17:11:06 -070043#include "src/core/lib/iomgr/exec_ctx.h"
44#include "src/core/lib/iomgr/iomgr_internal.h"
David Garcia Quintas0c47d802015-05-28 00:33:57 -070045
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +020046/* This holds the data for an outstanding read or write on a socket.
47 The mutex to protect the concurrent access to that data is the one
48 inside the winsocket wrapper. */
Craig Tillera82950e2015-09-22 12:33:20 -070049typedef struct grpc_winsocket_callback_info {
Nicolas "Pixel" Noble3d8e34d2015-02-10 11:05:48 +010050 /* This is supposed to be a WSAOVERLAPPED, but in order to get that
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +020051 definition, we need to include ws2tcpip.h, which needs to be included
52 from the top, otherwise it'll clash with a previous inclusion of
53 windows.h that in turns includes winsock.h. If anyone knows a way
54 to do it properly, feel free to send a patch. */
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +010055 OVERLAPPED overlapped;
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +020056 /* The callback information for the pending operation. May be empty if the
57 caller hasn't registered a callback yet. */
Craig Tiller82f9bd82015-09-23 09:31:51 -070058 grpc_closure *closure;
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +020059 /* A boolean to describe if the IO Completion Port got a notification for
60 that operation. This will happen if the operation completed before the
61 called had time to register a callback. We could avoid that behavior
62 altogether by forcing the caller to always register its callback before
63 proceeding queue an operation, but it is frequent for an IO Completion
64 Port to trigger quickly. This way we avoid a context switch for calling
65 the callback. We also simplify the read / write operations to avoid having
66 to hold a mutex for a long amount of time. */
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +010067 int has_pending_iocp;
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +020068 /* The results of the overlapped operation. */
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +010069 DWORD bytes_transfered;
70 int wsa_error;
71} grpc_winsocket_callback_info;
72
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +020073/* This is a wrapper to a Windows socket. A socket can have one outstanding
74 read, and one outstanding write. Doing an asynchronous accept means waiting
75 for a read operation. Doing an asynchronous connect means waiting for a
Nicolas "Pixel" Noblee34a45a2015-05-07 18:41:07 +020076 write operation. These are completely arbitrary ties between the operation
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +020077 and the kind of event, because we can have one overlapped per pending
78 operation, whichever its nature is. So we could have more dedicated pending
79 operation callbacks for connect and listen. But given the scope of listen
80 and accept, we don't need to go to that extent and waste memory. Also, this
81 is closer to what happens in posix world. */
Craig Tillera82950e2015-09-22 12:33:20 -070082typedef struct grpc_winsocket {
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +010083 SOCKET socket;
Craig Tiller5352ff12016-05-18 10:44:38 -070084 bool destroy_called;
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +010085
86 grpc_winsocket_callback_info write_info;
87 grpc_winsocket_callback_info read_info;
88
89 gpr_mu state_mu;
Craig Tillerd112ed92016-11-30 09:16:07 -080090 bool shutdown_called;
Nicolas Noble8703f4d2015-03-23 13:52:18 -070091
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +020092 /* You can't add the same socket twice to the same IO Completion Port.
93 This prevents that. */
Nicolas Noble8703f4d2015-03-23 13:52:18 -070094 int added_to_iocp;
David Garcia Quintas5f228f52015-05-26 19:58:50 -070095
Craig Tiller33825112015-09-18 07:44:19 -070096 grpc_closure shutdown_closure;
Craig Tiller33da3322015-06-02 10:29:40 -070097
98 /* A label for iomgr to track outstanding objects */
99 grpc_iomgr_object iomgr_object;
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +0100100} grpc_winsocket;
101
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +0200102/* Create a wrapped windows handle. This takes ownership of it, meaning that
103 it will be responsible for closing it. */
Craig Tillera82950e2015-09-22 12:33:20 -0700104grpc_winsocket *grpc_winsocket_create(SOCKET socket, const char *name);
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +0100105
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +0200106/* Initiate an asynchronous shutdown of the socket. Will call off any pending
Craig Tiller9f80fcf2015-08-28 08:22:48 -0700107 operation to cancel them. */
Craig Tillera82950e2015-09-22 12:33:20 -0700108void grpc_winsocket_shutdown(grpc_winsocket *socket);
Nicolas "Pixel" Noble0f981e92015-05-03 10:40:56 +0200109
Craig Tiller9f80fcf2015-08-28 08:22:48 -0700110/* Destroy a socket. Should only be called if there's no pending operation. */
Craig Tillera82950e2015-09-22 12:33:20 -0700111void grpc_winsocket_destroy(grpc_winsocket *socket);
Nicolas "Pixel" Noble21f627a2015-02-04 01:31:14 +0100112
Craig Tiller5352ff12016-05-18 10:44:38 -0700113void grpc_socket_notify_on_write(grpc_exec_ctx *exec_ctx,
114 grpc_winsocket *winsocket,
115 grpc_closure *closure);
116
117void grpc_socket_notify_on_read(grpc_exec_ctx *exec_ctx,
118 grpc_winsocket *winsocket,
119 grpc_closure *closure);
120
Craig Tiller95b90642016-05-18 12:12:44 -0700121void grpc_socket_become_ready(grpc_exec_ctx *exec_ctx,
122 grpc_winsocket *winsocket,
123 grpc_winsocket_callback_info *ci);
Craig Tiller5352ff12016-05-18 10:44:38 -0700124
Craig Tiller9a4dddd2016-03-25 17:08:13 -0700125#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */