1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "callbacks.h" // NOLINT(build/include)
16
17 #include <iostream>
18
19 size_t g_iterations = 0;
20 size_t constexpr kMaxIterations = 1'000'000;
21 static char g_buffer[1024];
22 static uv_buf_t g_iov;
23
24 // Stop the handle if the methods was called kMaxIterations times
IdleCallback(uv_idle_t * handle)25 void IdleCallback(uv_idle_t* handle) {
26 ++g_iterations;
27 if (g_iterations > kMaxIterations) {
28 std::cout << "IdleCallback was called " << kMaxIterations << " times"
29 << std::endl;
30 uv_idle_stop(handle);
31 }
32 }
33
34 // Called after some chars have been written
35 // As soon as writing of these bytes is completed, read more
OnWrite(uv_fs_t * req)36 void OnWrite(uv_fs_t* req) {
37 if (req->result < 0) {
38 std::cerr << "Write error: " << uv_strerror(static_cast<int>(req->result))
39 << std::endl;
40 return;
41 }
42 // Start reading more after writing these bytes
43 uv_fs_read(uv_default_loop(), &read_req, open_req.result, &g_iov, 1, -1,
44 OnRead);
45 }
46
47 // Called after some chars have been read
48 // As soon as reading of these bytes is completed, write them
OnRead(uv_fs_t * req)49 void OnRead(uv_fs_t* req) {
50 if (req->result < 0) {
51 std::cerr << "Read error: " << uv_strerror(req->result) << std::endl;
52 return;
53 }
54 if (req->result == 0) {
55 // No more bytes left, close the loop
56 uv_fs_t close_req;
57 uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL);
58 } else if (req->result > 0) {
59 // Start writing after reading some bytes
60 g_iov.len = req->result;
61 uv_fs_write(uv_default_loop(), &write_req, 1, &g_iov, 1, -1, OnWrite);
62 }
63 }
64
65 // Called after the file has been opened
66 // As soon as opening is completed, read the file
OnOpen(uv_fs_t * req)67 void OnOpen(uv_fs_t* req) {
68 if (req != &open_req) {
69 std::cerr << "Open error: req != &open_req" << std::endl;
70 return;
71 }
72 if (req->result < 0) {
73 std::cerr << "Open error: " << uv_strerror(static_cast<int>(req->result))
74 << std::endl;
75 return;
76 }
77 // Initialize uv_buf_t g_buffer
78 g_iov = uv_buf_init(g_buffer, sizeof(g_buffer));
79 // Start reading after opening
80 uv_fs_read(uv_default_loop(), &read_req, req->result, &g_iov, 1, -1, OnRead);
81 }
82
83 // Get the integer pointed by handle->data and increment it by one
84 // Then close the handle
TimerCallback(uv_timer_t * handle)85 void TimerCallback(uv_timer_t* handle) {
86 int* data = static_cast<int*>(
87 uv_handle_get_data(reinterpret_cast<uv_handle_t*>(handle)));
88 ++(*data);
89 uv_close(reinterpret_cast<uv_handle_t*>(handle), nullptr);
90 }
91