1 // Copyright 2016 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 #include <object/log_dispatcher.h>
8
9 #include <zircon/rights.h>
10 #include <zircon/syscalls/log.h>
11
12 #include <err.h>
13
14 #include <fbl/alloc_checker.h>
15 #include <fbl/auto_lock.h>
16
Create(uint32_t flags,fbl::RefPtr<Dispatcher> * dispatcher,zx_rights_t * rights)17 zx_status_t LogDispatcher::Create(uint32_t flags, fbl::RefPtr<Dispatcher>* dispatcher,
18 zx_rights_t* rights) {
19 fbl::AllocChecker ac;
20 auto disp = new (&ac) LogDispatcher(flags);
21 if (!ac.check()) return ZX_ERR_NO_MEMORY;
22
23 if (flags & ZX_LOG_FLAG_READABLE) {
24 dlog_reader_init(&disp->reader_, &LogDispatcher::Notify, disp);
25 }
26
27 *rights = default_rights();
28 *dispatcher = fbl::AdoptRef<Dispatcher>(disp);
29 return ZX_OK;
30 }
31
LogDispatcher(uint32_t flags)32 LogDispatcher::LogDispatcher(uint32_t flags)
33 : SoloDispatcher(ZX_LOG_WRITABLE), flags_(flags) {
34 }
35
~LogDispatcher()36 LogDispatcher::~LogDispatcher() {
37 if (flags_ & ZX_LOG_FLAG_READABLE) {
38 dlog_reader_destroy(&reader_);
39 }
40 }
41
Signal()42 void LogDispatcher::Signal() {
43 canary_.Assert();
44
45 UpdateState(0, ZX_CHANNEL_READABLE);
46 }
47
48 // static
Notify(void * cookie)49 void LogDispatcher::Notify(void* cookie) {
50 LogDispatcher* log = static_cast<LogDispatcher*>(cookie);
51 log->Signal();
52 }
53
Write(uint32_t flags,const void * ptr,size_t len)54 zx_status_t LogDispatcher::Write(uint32_t flags, const void* ptr, size_t len) {
55 canary_.Assert();
56
57 return dlog_write(flags_ | flags, ptr, len);
58 }
59
Read(uint32_t flags,void * ptr,size_t len,size_t * actual)60 zx_status_t LogDispatcher::Read(uint32_t flags, void* ptr, size_t len, size_t* actual) {
61 canary_.Assert();
62
63 if (!(flags_ & ZX_LOG_FLAG_READABLE))
64 return ZX_ERR_BAD_STATE;
65
66 Guard<fbl::Mutex> guard{get_lock()};
67
68 zx_status_t status = dlog_read(&reader_, 0, ptr, len, actual);
69 if (status == ZX_ERR_SHOULD_WAIT) {
70 UpdateStateLocked(ZX_CHANNEL_READABLE, 0);
71 }
72
73 return status;
74 }
75