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