Files
sdk/runtime/bin/eventhandler_linux.h
T
sgjesse@google.com 5950638350 Better handling of stdin/stdout/stderr
When using stdout/stderr it is no longer necessary to explicitly
close the streams for the program to terminate. The automatic
close is handled by always closing the associated receive port
for write only streams when not waiting for any events. If a
close or error handler is installed for stdout/stderr these will
still keep the program alive.

For stdin better handling of the difference between sockets and
pipes have been immplemented. As a special case for stdin when
reading from a terminal the a POLLIN signal with 0 available
bytes is treated as end-of-file. This will trigger when pressing
ctrl-d in a terminal as POLLHUP is not set in that situation.

R=ager@google.com

BUG=
TEST=

Review URL: http://codereview.chromium.org//8533005

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@1507 260f80e4-7a28-3924-810f-c04153c831b5
2011-11-14 14:47:58 +00:00

110 lines
2.5 KiB
C++

// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef BIN_EVENTHANDLER_LINUX_H_
#define BIN_EVENTHANDLER_LINUX_H_
#include <unistd.h>
#include <sys/socket.h>
class InterruptMessage {
public:
intptr_t id;
Dart_Port dart_port;
int64_t data;
};
enum PortDataFlags {
kClosedRead = 0,
kClosedWrite = 1,
};
class SocketData {
public:
intptr_t GetPollEvents();
void Unregister() {
port_ = 0;
mask_ = 0;
}
void ShutdownRead() {
shutdown(fd_, SHUT_RD);
MarkClosedRead();
}
void ShutdownWrite() {
shutdown(fd_, SHUT_WR);
MarkClosedWrite();
}
void Close() {
Unregister();
flags_ = 0;
close(fd_);
fd_ = 0;
}
bool IsListeningSocket() { return (mask_ & (1 << kListeningSocket)) != 0; }
bool IsPipe() { return (mask_ & (1 << kPipe)) != 0; }
bool IsClosedRead() { return (flags_ & (1 << kClosedRead)) != 0; }
bool IsClosedWrite() { return (flags_ & (1 << kClosedWrite)) != 0; }
void MarkClosedRead() { flags_ |= (1 << kClosedRead); }
void MarkClosedWrite() { flags_ |= (1 << kClosedWrite); }
bool HasPollEvents() { return mask_ != 0; }
void SetPortAndMask(Dart_Port port, intptr_t mask) {
port_ = port;
mask_ = mask;
}
intptr_t fd() { return fd_; }
void set_fd(intptr_t fd) { fd_ = fd; }
Dart_Port port() { return port_; }
intptr_t mask() { return mask_; }
private:
intptr_t fd_;
Dart_Port port_;
intptr_t mask_;
intptr_t flags_;
};
class EventHandlerImplementation {
public:
EventHandlerImplementation();
~EventHandlerImplementation();
SocketData* GetSocketData(intptr_t fd);
void SendData(intptr_t id, Dart_Port dart_port, intptr_t data);
void StartEventHandler();
private:
intptr_t GetTimeout();
bool GetInterruptMessage(InterruptMessage* msg);
struct pollfd* GetPollFds(intptr_t* size);
void HandleEvents(struct pollfd* pollfds, int pollfds_size, int result_size);
void HandleTimeout();
static void* Poll(void* args);
void WakeupHandler(intptr_t id, Dart_Port dart_port, int64_t data);
void HandleInterruptFd();
void SetPort(intptr_t fd, Dart_Port dart_port, intptr_t mask);
intptr_t GetPollEvents(struct pollfd* pollfd);
SocketData* socket_map_;
intptr_t socket_map_size_;
int64_t timeout_; // Time for next timeout.
Dart_Port timeout_port_;
int interrupt_fds_[2];
};
#endif // BIN_EVENTHANDLER_LINUX_H_