Bidirectional test mode signaling over GPIO
* Implements a bidirectional synchronous handshake protocol over
dut_flaga/b GPIOs. This protocol is designed to return true (test
mode) only if the DUT is connected to a servo board which implements
the remote end.
* Includes unit tests for the test mode signaling routine, complete with
mock/fake implementation of the remote end.
Note that we still do not deploy GpioHandler in actual update
processing, which will be done later.
BUG=chromium-os:25397,chromium-os:27109,chromium-os:27672
TEST=Builds and passes unit tests (including new ones)
Change-Id: I265407ed735c3e1354e10782ac30566b16caeb20
Reviewed-on: https://gerrit.chromium.org/gerrit/23330
Reviewed-by: Gaurav Shah <[email protected]>
Tested-by: Gilad Arnold <[email protected]>
Commit-Ready: Gilad Arnold <[email protected]>
Reviewed-by: Gilad Arnold <[email protected]>
diff --git a/file_descriptor.h b/file_descriptor.h
index 74749c6..67d7b14 100644
--- a/file_descriptor.h
+++ b/file_descriptor.h
@@ -28,6 +28,12 @@
// * Write() returns the number of bytes written: this appears to be more useful
// for clients, who may wish to retry or otherwise do something useful with
// the remaining data that was not written.
+//
+// * Provides a Reset() method, which will force to abandon a currently open
+// file descriptor and allow opening another file, without necessarily
+// properly closing the old one. This may be useful in cases where a "closer"
+// class does not care whether Close() was successful, but may need to reuse
+// the same file descriptor again.
namespace chromeos_update_engine {
@@ -53,14 +59,21 @@
// no bytes were written. Specific implementations may set errno accordingly.
virtual ssize_t Write(const void* buf, size_t count) = 0;
- // Wrapper around close. The descriptor must be open prior to this call.
+ // Closes a file descriptor. The descriptor must be open prior to this call.
// Returns true on success, false otherwise. Specific implementations may set
// errno accordingly.
virtual bool Close() = 0;
+ // Resets the file descriptor, abandoning a currently open file and returning
+ // the descriptor to the closed state.
+ virtual void Reset() = 0;
+
// Indicates whether or not an implementation sets meaningful errno.
virtual bool IsSettingErrno() = 0;
+ // Indicates whether the descriptor is currently open.
+ virtual bool IsOpen() = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(FileDescriptor);
};
@@ -77,26 +90,27 @@
virtual ssize_t Read(void* buf, size_t count);
virtual ssize_t Write(const void* buf, size_t count);
virtual bool Close();
+ virtual void Reset();
virtual bool IsSettingErrno() {
return true;
}
+ virtual bool IsOpen() {
+ return (fd_ >= 0);
+ }
private:
int fd_;
};
-// A scoped closer for a FileDescriptor object.
+// A scoped closer for a FileDescriptor object. The destructor of this class
+// invokes the Close() method of the given file descriptor, if it's not in the
+// closed state already. Note, however, that if Close() fails, this class will
+// force a Reset() invocation, which will abandon the current file descriptor.
class ScopedFileDescriptorCloser {
public:
explicit ScopedFileDescriptorCloser(FileDescriptor* descriptor)
: descriptor_(descriptor) {}
- ~ScopedFileDescriptorCloser() {
- if (descriptor_ && !descriptor_->Close())
- LOG(ERROR) << "FileDescriptor::Close failed: "
- << (descriptor_->IsSettingErrno() ?
- utils::ErrnoNumberAsString(errno) :
- "(no error code)");
- }
+ ~ScopedFileDescriptorCloser();
private:
FileDescriptor* descriptor_;