blob: 28bd02e78b3874162ae43f45e66a2a7b225a97e6 [file] [log] [blame]
Kaido Kertda45c042022-05-09 11:08:54 -07001// Copyright 2017 The Cobalt Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef STARBOARD_SHARED_WIN32_SOCKET_WAITER_INTERNAL_H_
16#define STARBOARD_SHARED_WIN32_SOCKET_WAITER_INTERNAL_H_
17
18#include <windows.h>
19#include <winsock2.h>
20
21#include <deque>
22#include <memory>
23#include <unordered_map>
24#include <vector>
25
26#include "starboard/common/mutex.h"
27#include "starboard/common/optional.h"
28#include "starboard/common/socket.h"
29#include "starboard/shared/internal_only.h"
30#include "starboard/shared/win32/auto_event_handle.h"
31#include "starboard/shared/win32/socket_internal.h"
32#include "starboard/socket_waiter.h"
33#include "starboard/thread.h"
34#include "starboard/types.h"
35
36namespace sbwin32 = starboard::shared::win32;
37
38#pragma warning(push)
39
40// SbSocketWaiterPrivate is defined as a struct, but for windows implementation
41// enough functionality has been added so that it warrants being a class
42// per Google's C++ style guide. This mismatch causes the Microsoft's compiler
43// to generate a warning.
44#pragma warning(disable : 4099)
45class SbSocketWaiterPrivate {
46 public:
47 SbSocketWaiterPrivate();
48 ~SbSocketWaiterPrivate();
49
50 // These methods implement the SbSocketWaiter API defined in socket_waiter.h.
51 bool Add(SbSocket socket,
52 void* context,
53 SbSocketWaiterCallback callback,
54 int interests,
55 bool persistent);
56 bool Remove(SbSocket socket);
57 void Wait();
Kaido Kertb1089432024-03-18 19:46:49 -070058 SbSocketWaiterResult WaitTimed(int64_t duration_usec);
Kaido Kertda45c042022-05-09 11:08:54 -070059 void WakeUp();
60 void HandleWakeUpRead();
61
62 private:
63 // A registration of a socket with a socket waiter.
64 struct Waitee {
65 Waitee(SbSocketWaiter waiter,
66 SbSocket socket,
67 void* context,
68 SbSocketWaiterCallback callback,
69 int interests,
70 bool persistent)
71 : waiter(waiter),
72 socket(socket),
73 context(context),
74 callback(callback),
75 interests(interests),
76 persistent(persistent) {}
77 // The waiter this event is registered with.
78 SbSocketWaiter waiter;
79
80 // The socket registered with the waiter.
81 SbSocket socket;
82
83 // A context value that will be passed to the callback.
84 void* context;
85
86 // The callback to call when one or more registered interests become ready.
87 SbSocketWaiterCallback callback;
88
89 // The set of interests registered with the waiter.
90 int interests;
91
92 // Whether this Waitee should stay registered after the next callback.
93 bool persistent;
94 };
95
96 class WaiteeRegistry {
97 public:
98 typedef int64_t LookupToken;
99 typedef std::deque<std::unique_ptr<Waitee>> Waitees;
100 typedef std::unordered_map<SbSocket, std::size_t> SocketToIndex;
101
102 WSAEVENT* GetHandleArray() { return socket_events_.data(); }
103 std::size_t GetHandleArraySize() { return socket_events_.size(); }
104 const Waitees& GetWaitees() const { return waitees_; }
105
106 // Gets the Waitee associated with the given socket, or nullptr.
107 Waitee* GetWaitee(SbSocket socket);
108
109 // Gets the index by socket
110 starboard::optional<int64_t> GetIndex(SbSocket socket);
111
112 // Gets the Waitee by index.
113 Waitee* GetWaiteeByIndex(LookupToken socket_index);
114
115 // Returns the index of the event.
116 LookupToken AddSocketEventAndWaitee(WSAEVENT socket_event,
117 std::unique_ptr<Waitee> waitee);
118 // Returns true if socket was found, and removed.
119 bool RemoveSocket(SbSocket socket);
120
121 private:
122 SocketToIndex socket_to_index_map_;
123 std::vector<WSAEVENT> socket_events_;
124 std::deque<std::unique_ptr<Waitee>> waitees_;
125 };
126
127 void SignalWakeupEvent();
128 void ResetWakeupEvent();
129
130 bool CheckSocketWaiterIsThis(SbSocket socket);
131
132 // The thread this waiter was created on. Immutable, so accessible from any
133 // thread.
Kaido Kert25902c62024-06-17 17:10:28 -0700134 const pthread_t thread_;
Kaido Kertda45c042022-05-09 11:08:54 -0700135
136 // The registry of currently registered Waitees.
137 WaiteeRegistry waitees_;
138 WaiteeRegistry::LookupToken wakeup_event_token_;
139
140 // This mutex covers the next two variables.
141 starboard::Mutex unhandled_wakeup_count_mutex_;
142 // Number of times wake up has been called, and not handled.
143 std::int32_t unhandled_wakeup_count_;
144 // The WSAEvent that is set by Wakeup();
145 sbwin32::AutoEventHandle wakeup_event_;
146};
147#pragma warning(pop)
148
149#endif // STARBOARD_SHARED_WIN32_SOCKET_WAITER_INTERNAL_H_