1 // Copyright 2018 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6 
7 #pragma once
8 
9 #include <fbl/canary.h>
10 #include <fbl/ref_ptr.h>
11 #include <object/dispatcher.h>
12 #include <object/port_dispatcher.h>
13 #include <zircon/types.h>
14 #include <vm/page_source.h>
15 
16 // Wrapper which maintains the object layer state of a PageSource.
17 class PageSourceWrapper : public PageSourceCallback,
18                           public fbl::DoublyLinkedListable<fbl::unique_ptr<PageSourceWrapper>> {
19 public:
20     PageSourceWrapper(PagerDispatcher* dispatcher, fbl::RefPtr<PortDispatcher> port, uint64_t key);
21     virtual ~PageSourceWrapper();
22 
23     void OnClose() override;
24 
25 private:
26     PagerDispatcher* const pager_;
27     const fbl::RefPtr<PortDispatcher> port_;
28     const uint64_t key_;
29 
30     fbl::Mutex mtx_;
31     bool closed_ TA_GUARDED(mtx_) = false;
32 
33     // The PageSource this is wrapping.
34     fbl::RefPtr<PageSource> src_ TA_GUARDED(mtx_);
35 
36     friend PagerDispatcher;
37 };
38 
39 class PagerDispatcher final : public SoloDispatcher<PagerDispatcher, ZX_DEFAULT_PAGER_RIGHTS> {
40 public:
41     static zx_status_t Create(fbl::RefPtr<Dispatcher>* dispatcher, zx_rights_t* rights);
42     ~PagerDispatcher() final;
43 
44     zx_status_t CreateSource(fbl::RefPtr<PortDispatcher> port,
45                              uint64_t key, fbl::RefPtr<PageSource>* src);
46     void ReleaseSource(PageSourceWrapper* src);
47 
get_type()48     zx_obj_type_t get_type() const final { return ZX_OBJ_TYPE_PAGER; }
49 
50     void on_zero_handles() final;
51 
52 private:
53     explicit PagerDispatcher();
54 
55     fbl::Canary<fbl::magic("PGRD")> canary_;
56 
57     fbl::Mutex mtx_;
58     fbl::DoublyLinkedList<fbl::unique_ptr<PageSourceWrapper>> srcs_;
59 };
60