hwmonio.cpp (e289100ec0dc9944439092d1d8f97de8123ed9c6) hwmonio.cpp (043d32306e00484afc446a44789b61869ea14f84)
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14#include "config.h"
15
16#include "hwmonio.hpp"
17
18#include "sysfs.hpp"
19
14#include <algorithm>
15#include <exception>
16#include <fstream>
17#include <thread>
18
20#include <algorithm>
21#include <exception>
22#include <fstream>
23#include <thread>
24
19#include "config.h"
20#include "hwmonio.hpp"
21#include "sysfs.hpp"
25namespace hwmonio
26{
22
27
23namespace hwmonio {
24
25static constexpr auto retryableErrors = {
26 /*
27 * Retry on bus or device errors or timeouts in case
28 * they are transient.
29 */
30 EIO,
31 ETIMEDOUT,
32

--- 34 unchanged lines hidden (view full) ---

67 */
68 EMSGSIZE,
69};
70
71HwmonIO::HwmonIO(const std::string& path) : p(path)
72{
73}
74
28static constexpr auto retryableErrors = {
29 /*
30 * Retry on bus or device errors or timeouts in case
31 * they are transient.
32 */
33 EIO,
34 ETIMEDOUT,
35

--- 34 unchanged lines hidden (view full) ---

70 */
71 EMSGSIZE,
72};
73
74HwmonIO::HwmonIO(const std::string& path) : p(path)
75{
76}
77
75int64_t HwmonIO::read(
76 const std::string& type,
77 const std::string& id,
78 const std::string& sensor,
79 size_t retries,
80 std::chrono::milliseconds delay) const
78int64_t HwmonIO::read(const std::string& type, const std::string& id,
79 const std::string& sensor, size_t retries,
80 std::chrono::milliseconds delay) const
81{
82 int64_t val;
83 std::ifstream ifs;
81{
82 int64_t val;
83 std::ifstream ifs;
84 auto fullPath = sysfs::make_sysfs_path(
85 p, type, id, sensor);
84 auto fullPath = sysfs::make_sysfs_path(p, type, id, sensor);
86
85
87 ifs.exceptions(
88 std::ifstream::failbit |
89 std::ifstream::badbit |
90 std::ifstream::eofbit);
86 ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit |
87 std::ifstream::eofbit);
91
92 while (true)
93 {
94 try
95 {
96 errno = 0;
97 if (!ifs.is_open())
98 ifs.open(fullPath);

--- 8 unchanged lines hidden (view full) ---

107 if (!rc)
108 {
109 throw;
110 }
111
112 if (rc == ENOENT || rc == ENODEV)
113 {
114 // If the directory or device disappeared then this application
88
89 while (true)
90 {
91 try
92 {
93 errno = 0;
94 if (!ifs.is_open())
95 ifs.open(fullPath);

--- 8 unchanged lines hidden (view full) ---

104 if (!rc)
105 {
106 throw;
107 }
108
109 if (rc == ENOENT || rc == ENODEV)
110 {
111 // If the directory or device disappeared then this application
115 // should gracefully exit. There are race conditions between the
116 // unloading of a hwmon driver and the stopping of this service
117 // by systemd. To prevent this application from falsely failing
118 // in these scenarios, it will simply exit if the directory or
119 // file can not be found. It is up to the user(s) of this
120 // provided hwmon object to log the appropriate errors if the
121 // object disappears when it should not.
112 // should gracefully exit. There are race conditions between
113 // the unloading of a hwmon driver and the stopping of this
114 // service by systemd. To prevent this application from falsely
115 // failing in these scenarios, it will simply exit if the
116 // directory or file can not be found. It is up to the user(s)
117 // of this provided hwmon object to log the appropriate errors
118 // if the object disappears when it should not.
122 exit(0);
123 }
124
119 exit(0);
120 }
121
125 if (0 == std::count(
126 retryableErrors.begin(),
127 retryableErrors.end(),
128 rc) ||
129 !retries)
122 if (0 == std::count(retryableErrors.begin(), retryableErrors.end(),
123 rc) ||
124 !retries)
130 {
131 // Not a retryable error or out of retries.
132#ifdef NEGATIVE_ERRNO_ON_FAIL
133 return -rc;
134#endif
135
136 // Work around GCC bugs 53984 and 66145 for callers by
137 // explicitly raising system_error here.

--- 5 unchanged lines hidden (view full) ---

143 continue;
144 }
145 break;
146 }
147
148 return val;
149}
150
125 {
126 // Not a retryable error or out of retries.
127#ifdef NEGATIVE_ERRNO_ON_FAIL
128 return -rc;
129#endif
130
131 // Work around GCC bugs 53984 and 66145 for callers by
132 // explicitly raising system_error here.

--- 5 unchanged lines hidden (view full) ---

138 continue;
139 }
140 break;
141 }
142
143 return val;
144}
145
151void HwmonIO::write(
152 uint32_t val,
153 const std::string& type,
154 const std::string& id,
155 const std::string& sensor,
156 size_t retries,
157 std::chrono::milliseconds delay) const
146void HwmonIO::write(uint32_t val, const std::string& type,
147 const std::string& id, const std::string& sensor,
148 size_t retries, std::chrono::milliseconds delay) const
158
159{
160 std::ofstream ofs;
149
150{
151 std::ofstream ofs;
161 auto fullPath = sysfs::make_sysfs_path(
162 p, type, id, sensor);
152 auto fullPath = sysfs::make_sysfs_path(p, type, id, sensor);
163
153
164 ofs.exceptions(
165 std::ofstream::failbit |
166 std::ofstream::badbit |
167 std::ofstream::eofbit);
154 ofs.exceptions(std::ofstream::failbit | std::ofstream::badbit |
155 std::ofstream::eofbit);
168
169 // See comments in the read method for an explanation of the odd exception
170 // handling behavior here.
171
172 while (true)
173 {
174 try
175 {

--- 14 unchanged lines hidden (view full) ---

190 throw;
191 }
192
193 if (rc == ENOENT)
194 {
195 exit(0);
196 }
197
156
157 // See comments in the read method for an explanation of the odd exception
158 // handling behavior here.
159
160 while (true)
161 {
162 try
163 {

--- 14 unchanged lines hidden (view full) ---

178 throw;
179 }
180
181 if (rc == ENOENT)
182 {
183 exit(0);
184 }
185
198 if (0 == std::count(
199 retryableErrors.begin(),
200 retryableErrors.end(),
201 rc) ||
202 !retries)
186 if (0 == std::count(retryableErrors.begin(), retryableErrors.end(),
187 rc) ||
188 !retries)
203 {
204 // Not a retryable error or out of retries.
205
206 // Work around GCC bugs 53984 and 66145 for callers by
207 // explicitly raising system_error here.
208 throw std::system_error(rc, std::generic_category());
209 }
210

--- 5 unchanged lines hidden (view full) ---

216 }
217}
218
219std::string HwmonIO::path() const
220{
221 return p;
222}
223
189 {
190 // Not a retryable error or out of retries.
191
192 // Work around GCC bugs 53984 and 66145 for callers by
193 // explicitly raising system_error here.
194 throw std::system_error(rc, std::generic_category());
195 }
196

--- 5 unchanged lines hidden (view full) ---

202 }
203}
204
205std::string HwmonIO::path() const
206{
207 return p;
208}
209
224} // hwmonio
210} // namespace hwmonio