• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Dawn Authors
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 DAWNWIRE_CLIENT_REQUESTTRACKER_H_
16 #define DAWNWIRE_CLIENT_REQUESTTRACKER_H_
17 
18 #include "common/Assert.h"
19 #include "common/NonCopyable.h"
20 
21 #include <cstdint>
22 #include <map>
23 
24 namespace dawn_wire { namespace client {
25 
26     class Device;
27     class MemoryTransferService;
28 
29     template <typename Request>
30     class RequestTracker : NonCopyable {
31       public:
~RequestTracker()32         ~RequestTracker() {
33             ASSERT(mRequests.empty());
34         }
35 
Add(Request && request)36         uint64_t Add(Request&& request) {
37             mSerial++;
38             mRequests.emplace(mSerial, request);
39             return mSerial;
40         }
41 
Acquire(uint64_t serial,Request * request)42         bool Acquire(uint64_t serial, Request* request) {
43             auto it = mRequests.find(serial);
44             if (it == mRequests.end()) {
45                 return false;
46             }
47             *request = std::move(it->second);
48             mRequests.erase(it);
49             return true;
50         }
51 
52         template <typename CloseFunc>
CloseAll(CloseFunc && closeFunc)53         void CloseAll(CloseFunc&& closeFunc) {
54             // Call closeFunc on all requests while handling reentrancy where the callback of some
55             // requests may add some additional requests. We guarantee all callbacks for requests
56             // are called exactly onces, so keep closing new requests if the first batch added more.
57             // It is fine to loop infinitely here if that's what the application makes use do.
58             while (!mRequests.empty()) {
59                 // Move mRequests to a local variable so that further reentrant modifications of
60                 // mRequests don't invalidate the iterators.
61                 auto allRequests = std::move(mRequests);
62                 for (auto& it : allRequests) {
63                     closeFunc(&it.second);
64                 }
65             }
66         }
67 
68         template <typename F>
ForAll(F && f)69         void ForAll(F&& f) {
70             for (auto& it : mRequests) {
71                 f(&it.second);
72             }
73         }
74 
75       private:
76         uint64_t mSerial;
77         std::map<uint64_t, Request> mRequests;
78     };
79 
80 }}  // namespace dawn_wire::client
81 
82 #endif  // DAWNWIRE_CLIENT_REQUESTTRACKER_H_
83