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