CCF
Loading...
Searching...
No Matches
handle_ring_buffer.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
5#include "../ds/files.h"
6#include "../enclave/interface.h"
7#include "ccf/ds/logger.h"
8#include "timer.h"
9
10#include <chrono>
11#include <ctime>
12#include <iomanip>
13#include <nlohmann/json.hpp>
14#include <string>
15#include <sys/types.h>
16#include <unistd.h>
17
18namespace asynchost
19{
21 {
22 private:
23 // Maximum number of outbound ringbuffer messages which will be processed in
24 // a single iteration
25 static constexpr size_t max_messages = 256;
26
30
31 public:
36 bp(bp),
37 r(r),
38 nbwf(nbwf)
39 {
40 // Register message handler for log message from enclave
42 bp, AdminMessage::log_msg, [](const uint8_t* data, size_t size) {
43 auto
44 [log_time_us_count,
45 file_name,
46 line_number,
47 log_level,
48 tag,
49 thread_id,
50 msg] = ringbuffer::read_message<AdminMessage::log_msg>(data, size);
51
53 log_level, tag, file_name.c_str(), line_number, thread_id);
54 ll.msg = msg;
55
56 // Represent offset as a real (counting seconds) to handle both small
57 // negative _and_ positive numbers. Since the system clock used is not
58 // monotonic, the offset we calculate could go in either direction,
59 // and tm can't represent small negative values.
60 std::optional<double> offset_time = std::nullopt;
61
62 // If enclave doesn't know the
63 // current time yet, don't try to produce an offset, just give them
64 // the host's time (producing offset of 0)
65 if (log_time_us_count != 0)
66 {
67 // Enclave time is recomputed every time. If multiple threads
68 // log inside the enclave, offsets may not always increase
69 const double enclave_time_s = log_time_us_count / 1'000'000.0;
70
71 ::timespec ts;
72 ::timespec_get(&ts, TIME_UTC);
73 const double host_time_s =
74 ts.tv_sec + (ts.tv_nsec / 1'000'000'000.0);
75
76 offset_time = enclave_time_s - host_time_s;
77 }
78
79 auto& loggers = ccf::logger::config::loggers();
80 for (auto const& logger : loggers)
81 {
82 logger->write(ll, offset_time);
83 }
84 });
85
87 bp,
88 AdminMessage::fatal_error_msg,
89 [](const uint8_t* data, size_t size) {
90 auto [msg] =
91 ringbuffer::read_message<AdminMessage::fatal_error_msg>(data, size);
92
93 std::cerr << msg << std::endl << std::flush;
94 throw std::logic_error(msg);
95 });
96
98 bp, AdminMessage::stopped, [](const uint8_t*, size_t) {
99 uv_stop(uv_default_loop());
100 LOG_INFO_FMT("Host stopped successfully");
101 });
102 }
103
104 void on_timer()
105 {
106 // Regularly read (and process) some outbound ringbuffer messages...
107 bp.read_n(max_messages, r);
108
109 // ...flush any pending inbound messages...
110 nbwf.flush_all_inbound();
111 }
112 };
113
115}
Definition handle_ring_buffer.h:21
HandleRingbufferImpl(messaging::BufferProcessor &bp, ringbuffer::Reader &r, ringbuffer::NonBlockingWriterFactory &nbwf)
Definition handle_ring_buffer.h:32
void on_timer()
Definition handle_ring_buffer.h:104
Definition proxy.h:50
static std::vector< std::unique_ptr< AbstractLogger > > & loggers()
Definition logger.h:273
Definition messaging.h:211
size_t read_n(size_t max_messages, ringbuffer::Reader &r)
Definition messaging.h:240
Definition non_blocking.h:186
bool flush_all_inbound()
Definition non_blocking.h:249
Definition ring_buffer.h:175
#define LOG_INFO_FMT
Definition logger.h:395
#define DISPATCHER_SET_MESSAGE_HANDLER(DISP, MSG,...)
Definition messaging.h:316
Definition after_io.h:8
Definition logger.h:45
std::string msg
Definition logger.h:55