1 #include "pipe_pager.h" 2 #include "pipe_object_server.h" 3 4 5 6 /* Initialise a pager for a pipe with a shared page mapper for moderating 7 access to loaded pages. At first, no mapper will be configured: this must be 8 done by requesting a region. */ 9 10 PipePager::PipePager(PipePaging *paging, bool writing) 11 : Pager(NULL, writing ? L4_FPAGE_RW : L4_FPAGE_RO), 12 _paging(paging), _writing(writing) 13 { 14 /* Initialise the size of the paged region. */ 15 16 _size = _paging->region_size(); 17 } 18 19 int PipePager::expected_items() 20 { 21 return PipeObject_expected_items; 22 } 23 24 ipc_server_handler_type PipePager::handler() 25 { 26 return (ipc_server_handler_type) handle_PipeObject; 27 } 28 29 30 31 /* Close the pager, releasing the paging coordinator for the pipe. This will 32 release all active page mappers. */ 33 34 void PipePager::close() 35 { 36 _paging->detach(); 37 } 38 39 /* Support paging. */ 40 41 long PipePager::map(unsigned long offset, l4_addr_t hot_spot, flags_t flags, l4_snd_fpage_t *region) 42 { 43 return Pager::map(offset, hot_spot, flags, region); 44 } 45 46 47 48 /* Return details of the current region. */ 49 50 long PipePager::current_region(offset_t *populated_size, offset_t *size) 51 { 52 if (_mapper != NULL) 53 { 54 *populated_size = _mapper->get_data_size(); 55 *size = _size; 56 return L4_EOK; 57 } 58 else 59 return -L4_EIO; 60 } 61 62 /* Obtain the next region and its details. */ 63 64 long PipePager::next_region(offset_t *populated_size, offset_t *size) 65 { 66 /* Obtain a new region if writing. */ 67 68 if (_writing) 69 return next_region_for_writer(populated_size, size); 70 else 71 return next_region_for_reader(populated_size, size); 72 } 73 74 long PipePager::next_region_for_reader(offset_t *populated_size, offset_t *size) 75 { 76 PageMapper *mapper = _paging->next_region(); 77 78 if (mapper == NULL) 79 return -L4_EIO; 80 81 _mapper = mapper; 82 83 return current_region(populated_size, size); 84 } 85 86 long PipePager::next_region_for_writer(offset_t *populated_size, offset_t *size) 87 { 88 /* Set the populated size before moving on. */ 89 90 if (_mapper != NULL) 91 _mapper->set_data_size(*populated_size); 92 93 /* Obtain the page mapper for the region. */ 94 95 PageMapper *mapper = _paging->add_region(); 96 97 if (mapper == NULL) 98 return -L4_EIO; 99 100 _mapper = mapper; 101 102 return current_region(populated_size, size); 103 } 104 105 // vim: tabstop=4 expandtab shiftwidth=4