1 // 2 // 3 // Copyright 2015 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #ifndef GRPC_SRC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H 20 #define GRPC_SRC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H 21 22 #include <grpc/support/port_platform.h> 23 24 #include "src/core/lib/iomgr/port.h" 25 26 #ifdef GRPC_WINSOCK_SOCKET 27 #include <winsock2.h> 28 29 #include <grpc/support/atm.h> 30 #include <grpc/support/sync.h> 31 32 #include "src/core/lib/iomgr/closure.h" 33 #include "src/core/lib/iomgr/iomgr_internal.h" 34 35 #ifndef WSA_FLAG_NO_HANDLE_INHERIT 36 #define WSA_FLAG_NO_HANDLE_INHERIT 0x80 37 #endif 38 39 // This holds the data for an outstanding read or write on a socket. 40 // The mutex to protect the concurrent access to that data is the one 41 // inside the winsocket wrapper. 42 typedef struct grpc_winsocket_callback_info { 43 // This is supposed to be a WSAOVERLAPPED, but in order to get that 44 // definition, we need to include ws2tcpip.h, which needs to be included 45 // from the top, otherwise it'll clash with a previous inclusion of 46 // windows.h that in turns includes winsock.h. If anyone knows a way 47 // to do it properly, feel free to send a patch. 48 OVERLAPPED overlapped; 49 // The callback information for the pending operation. May be empty if the 50 // caller hasn't registered a callback yet. 51 grpc_closure* closure; 52 // A boolean to describe if the IO Completion Port got a notification for 53 // that operation. This will happen if the operation completed before the 54 // called had time to register a callback. We could avoid that behavior 55 // altogether by forcing the caller to always register its callback before 56 // proceeding queue an operation, but it is frequent for an IO Completion 57 // Port to trigger quickly. This way we avoid a context switch for calling 58 // the callback. We also simplify the read / write operations to avoid having 59 // to hold a mutex for a long amount of time. 60 int has_pending_iocp; 61 // The results of the overlapped operation. 62 DWORD bytes_transferred; 63 int wsa_error; 64 // Tracks whether the final closure has already been run when the socket is 65 // shut down. This allows closures to be run immediately upon socket shutdown. 66 bool closure_already_executed_at_shutdown = false; 67 } grpc_winsocket_callback_info; 68 69 // This is a wrapper to a Windows socket. A socket can have one outstanding 70 // read, and one outstanding write. Doing an asynchronous accept means waiting 71 // for a read operation. Doing an asynchronous connect means waiting for a 72 // write operation. These are completely arbitrary ties between the operation 73 // and the kind of event, because we can have one overlapped per pending 74 // operation, whichever its nature is. So we could have more dedicated pending 75 // operation callbacks for connect and listen. But given the scope of listen 76 // and accept, we don't need to go to that extent and waste memory. Also, this 77 // is closer to what happens in posix world. 78 typedef struct grpc_winsocket { 79 SOCKET socket; 80 bool destroy_called; 81 82 grpc_winsocket_callback_info write_info; 83 grpc_winsocket_callback_info read_info; 84 85 gpr_mu state_mu; 86 bool shutdown_called; 87 bool shutdown_registered; 88 89 // You can't add the same socket twice to the same IO Completion Port. 90 // This prevents that. 91 int added_to_iocp; 92 93 // A label for iomgr to track outstanding objects 94 grpc_iomgr_object iomgr_object; 95 } grpc_winsocket; 96 97 // Create a wrapped windows handle. This takes ownership of it, meaning that 98 // it will be responsible for closing it. 99 grpc_winsocket* grpc_winsocket_create(SOCKET socket, const char* name); 100 101 SOCKET grpc_winsocket_wrapped_socket(grpc_winsocket* socket); 102 103 // Initiate an asynchronous shutdown of the socket. Will call off any pending 104 // operation to cancel them. 105 void grpc_winsocket_shutdown(grpc_winsocket* socket); 106 107 // Destroy a socket. Should only be called if there's no pending operation. 108 void grpc_winsocket_destroy(grpc_winsocket* socket); 109 110 void grpc_socket_notify_on_write(grpc_winsocket* winsocket, 111 grpc_closure* closure); 112 113 void grpc_socket_notify_on_read(grpc_winsocket* winsocket, 114 grpc_closure* closure); 115 116 bool grpc_socket_become_ready(grpc_winsocket* socket, 117 grpc_winsocket_callback_info* info); 118 119 // Returns true if this system can create AF_INET6 sockets bound to ::1. 120 // The value is probed once, and cached for the life of the process. 121 int grpc_ipv6_loopback_available(void); 122 123 void grpc_wsa_socket_flags_init(); 124 125 DWORD grpc_get_default_wsa_socket_flags(); 126 127 // Final cleanup operations on the socket prior to deletion. 128 void grpc_winsocket_finish(grpc_winsocket*); 129 130 #endif 131 132 #endif // GRPC_SRC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H 133