blob: 5265414ce738d6b0d58f67e9aecfcb84ed4075b7 [file] [log] [blame]
// Copyright 2012 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVTOOLS_GOMA_CLIENT_SOCKET_DESCRIPTOR_H_
#define DEVTOOLS_GOMA_CLIENT_SOCKET_DESCRIPTOR_H_
#include <memory>
#include "basictypes.h"
#include "scoped_fd.h"
#include "worker_thread_manager.h"
#include "descriptor.h"
namespace devtools_goma {
class SocketDescriptor : public Descriptor {
public:
SocketDescriptor(ScopedSocket&& fd,
WorkerThreadManager::Priority priority,
WorkerThreadManager::WorkerThread* worker);
~SocketDescriptor() override;
virtual int fd() const { return fd_.get(); }
virtual const IOChannel* wrapper() const { return &fd_; }
ScopedSocket ReleaseFd() { return std::move(fd_); }
virtual WorkerThreadManager::Priority priority() const { return priority_; }
SocketDescriptor* socket_descriptor() override { return this; }
// closure must be permanent closure.
void NotifyWhenReadable(
std::unique_ptr<PermanentClosure> closure) override;
// closure must be permanent closure.
void NotifyWhenWritable(
std::unique_ptr<PermanentClosure> closure) override;
virtual void ClearReadable();
void ClearWritable() override;
// closure must be one-shot closure.
void NotifyWhenTimedout(double timeout,
OneshotClosure* closure) override;
void ChangeTimeout(double timeout) override;
virtual void ClearTimeout();
ssize_t Read(void* ptr, size_t len) override;
ssize_t Write(const void* ptr, size_t len) override;
bool NeedRetry() const override;
virtual int ShutdownForSend();
string GetLastErrorMessage() const override { return last_error_message_; }
virtual bool IsReadable() const;
bool IsClosed() const { return is_closed_; }
bool CanReuse() const override {
return !IsClosed() && last_error_message_.empty();
}
void StopRead() override;
void StopWrite() override;
virtual void RestartRead();
virtual void RestartWrite();
void UnregisterWritable();
bool wait_readable() const;
bool wait_writable() const;
OneshotClosure* GetReadableClosure();
OneshotClosure* GetWritableClosure();
OneshotClosure* GetTimeoutClosure();
private:
// Gets a one-shot closure to run permanent "closure" and
// mark a closure in run queue, so that it won't add new closure in run
// queue while the closure is waiting to run.
// If the closure is not permanent closure, make sure delete closure when
// GetClosure() returns nullptr, or check *in_queue is false before calling
// GetClosure().
OneshotClosure* GetClosure(bool* in_queue, bool* active,
PermanentClosure* closure);
// Marks no closure in run queue and runs permanent "closure".
// If not active_, it doesn't run closure.
void RunCallback(PermanentClosure* closure, bool* in_queue, bool* active);
// Fires timeout.
// If read or write closure in queue while this closure has been pending
// in queue, cancel timeout.
void TimeoutClosure();
void UpdateLastErrorStatus();
ScopedSocket fd_;
const WorkerThreadManager::Priority priority_;
WorkerThreadManager::WorkerThread* worker_;
// permanent closure.
std::unique_ptr<PermanentClosure> readable_closure_;
// permanent closure.
std::unique_ptr<PermanentClosure> writable_closure_;
double timeout_;
double last_time_;
// permanent to TimeoutClosure()
std::unique_ptr<PermanentClosure> timeout_run_closure_;
// single shot specified by NotifyWhenTimeout.
std::unique_ptr<OneshotClosure> timeout_closure_;
WorkerThreadManager::ThreadId thread_;
bool read_in_queue_;
bool write_in_queue_;
bool timeout_in_queue_;
bool active_read_;
bool active_write_;
string last_error_message_;
bool write_poll_registered_;
bool is_closed_;
bool need_retry_;
DISALLOW_COPY_AND_ASSIGN(SocketDescriptor);
};
} // namespace devtools_goma
#endif // DEVTOOLS_GOMA_CLIENT_SOCKET_DESCRIPTOR_H_