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 17zx_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 = ZX_DEFAULT_LOG_RIGHTS; 28 *dispatcher = fbl::AdoptRef<Dispatcher>(disp); 29 return ZX_OK; 30} 31 32LogDispatcher::LogDispatcher(uint32_t flags) 33 : SoloDispatcher(ZX_LOG_WRITABLE), flags_(flags) { 34} 35 36LogDispatcher::~LogDispatcher() { 37 if (flags_ & ZX_LOG_FLAG_READABLE) { 38 dlog_reader_destroy(&reader_); 39 } 40} 41 42void LogDispatcher::Signal() { 43 canary_.Assert(); 44 45 UpdateState(0, ZX_CHANNEL_READABLE); 46} 47 48// static 49void LogDispatcher::Notify(void* cookie) { 50 LogDispatcher* log = static_cast<LogDispatcher*>(cookie); 51 log->Signal(); 52} 53 54zx_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 60zx_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