Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin' into 1.8.7
Browse files Browse the repository at this point in the history
Conflicts:
	gems_list.txt
brixen committed May 7, 2015
2 parents 524e28b + 0e2ace2 commit 8e023e1
Showing 14 changed files with 258 additions and 185 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
daedalus-core (0.2.0)
daedalus-core (0.3.0)
rake (10.4.2)
redcard (1.1.0)
rubinius-ast (1.3.0)
2 changes: 1 addition & 1 deletion kernel/common/type.rb
Original file line number Diff line number Diff line change
@@ -355,7 +355,7 @@ def self.include_modules_from(included_module, klass)
changed = true
end

constants_changed ||= mod.constants.any?
constants_changed ||= mod.constant_table.size > 0
end

mod = mod.direct_superclass
4 changes: 0 additions & 4 deletions kernel/delta/console.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
module Rubinius
module Console
class Server
# The following constants are set internally:
# RequestPath - the path to the console request file for this process
# ResponsePath - the path to the console response file for this process

attr_reader :inbox
attr_reader :outbox
attr_reader :thread
3 changes: 2 additions & 1 deletion kernel/delta/struct.rb
Original file line number Diff line number Diff line change
@@ -92,9 +92,10 @@ def length
CODE

begin
include Module.new do
mod = Module.new do
module_eval code
end
include mod
rescue SyntaxError
# SyntaxError means that something is wrong with the
# specialization code. Just eat the error and don't specialize.
9 changes: 3 additions & 6 deletions library/rubinius/configuration.rb
Original file line number Diff line number Diff line change
@@ -176,14 +176,11 @@
s.vm_variable "tmp", "$TMPDIR",
"Default temp/fallback directory for the process"

s.vm_variable "fsapi.path", "$TMPDIR/$PROGRAM_NAME-$USER-$PID",
"Base directory of the Rubinius File System API files"

s.vm_variable "fsapi.access", 0750,
"Permissions on the Rubinius File System API directory"
s.vm_variable "console.path", "$TMPDIR/$PROGRAM_NAME-$USER-console",
"Path for Rubinius Console connection file"

s.vm_variable "console.access", 0660,
"Permissions on the Rubinius Console files"
"Permissions on the Rubinius Console connection file"

s.vm_variable "log", "$TMPDIR/$PROGRAM_NAME-$USER.log",
"Logging facility to use: 'syslog', 'console', or path"
207 changes: 147 additions & 60 deletions vm/console.cpp
Original file line number Diff line number Diff line change
@@ -26,12 +26,15 @@
#include <sys/types.h>

#include <stdio.h>
#include <libgen.h>

// read
#include <unistd.h>
#include <sys/uio.h>
#include <sys/types.h>

#include <ostream>

namespace rubinius {
using namespace utilities;

@@ -53,37 +56,31 @@ namespace rubinius {
return fd;
}

Request::Request(STATE, Console* console)
Request::Request(STATE, Console* console, Response* response)
: InternalThread(state, "rbx.console.request")
, console_(console)
, response_(console->response())
, response_(response)
, enabled_(false)
, fd_(-1)
, fsevent_(state)
{
}

void Request::initialize(STATE) {
path_ = state->shared().fsapi_path + "/console-request";
console_->server_class(state)->set_const(state, state->symbol("RequestPath"),
String::create(state, path_.c_str()));
}

void Request::setup_request(STATE) {
if((fd_ = open_file(state, path_)) < 0) {
if((fd_ = open_file(state, console_->request_path())) < 0) {
logger::error("%s: console request: unable to open file", strerror(errno));
return;
}

FSEvent* fsevent = FSEvent::create(state);
fsevent->watch_file(state, fd_, path_.c_str());
fsevent->watch_file(state, fd_, console_->request_path().c_str());
fsevent_.set(fsevent);

enabled_ = true;
}

void Request::start_thread(STATE) {
setup_request(state);
if(!enabled_) return;

InternalThread::start_thread(state);
}
@@ -96,7 +93,7 @@ namespace rubinius {
}
}

void Request::close_request(STATE) {
void Request::close_request() {
if(fd_ > 0) {
close(fd_);
fd_ = -1;
@@ -106,22 +103,11 @@ namespace rubinius {
void Request::stop_thread(STATE) {
InternalThread::stop_thread(state);

close_request(state);
unlink(path_.c_str());
}

void Request::before_exec(STATE) {
stop_thread(state);
}

void Request::after_exec(STATE) {
start(state);
close_request();
}

void Request::after_fork_child(STATE) {
close_request(state);

InternalThread::after_fork_child(state);
close_request();
}

char* Request::read_request(STATE) {
@@ -182,9 +168,15 @@ namespace rubinius {
Response::Response(STATE, Console* console)
: InternalThread(state, "rbx.console.response")
, console_(console)
, inbox_(state)
, outbox_(state)
, fd_(-1)
, request_list_(NULL)
{
inbox_.set(as<Channel>(
console_->ruby_console()->get_ivar(state, state->symbol("@inbox"))));
outbox_.set(as<Channel>(
console_->ruby_console()->get_ivar(state, state->symbol("@outbox"))));
}

Response::~Response() {
@@ -193,15 +185,11 @@ namespace rubinius {
}

void Response::initialize(STATE) {
path_ = state->shared().fsapi_path + "/console-response";
console_->server_class(state)->set_const(state, state->symbol("ResponsePath"),
String::create(state, path_.c_str()));

Thread::create(state, vm());
}

void Response::start_thread(STATE) {
if((fd_ = open_file(state, path_)) < 0) {
if((fd_ = open_file(state, console_->response_path())) < 0) {
logger::error("%s: console response: unable to open file", strerror(errno));
return;
}
@@ -218,17 +206,20 @@ namespace rubinius {
void Response::wakeup(STATE) {
InternalThread::wakeup(state);

GCTokenImpl gct;
inbox_.get()->send(state, gct, String::create(state, ""), 0);

response_cond_.signal();
}

void Response::close_response(STATE) {
void Response::close_response() {
if(fd_ > 0) {
close(fd_);
fd_ = -1;
}
}

void Response::clear_requests(STATE) {
void Response::clear_requests() {
if(request_list_) {
for(RequestList::const_iterator i = request_list_->begin();
i != request_list_->end();
@@ -244,25 +235,11 @@ namespace rubinius {
void Response::stop_thread(STATE) {
InternalThread::stop_thread(state);

clear_requests(state);

close_response(state);
unlink(path_.c_str());
}

void Response::before_exec(STATE) {
stop_thread(state);
}

void Response::after_exec(STATE) {
start(state);
close_response();
}

void Response::after_fork_child(STATE) {
close_response(state);
clear_requests(state);

InternalThread::after_fork_child(state);
close_response();
}

void Response::send_request(STATE, const char* request) {
@@ -301,10 +278,8 @@ namespace rubinius {
size_t pending_requests = 0;
char* request = NULL;

Channel* inbox = as<Channel>(
console_->ruby_console()->get_ivar(state, state->symbol("@inbox")));
Channel* outbox = as<Channel>(
console_->ruby_console()->get_ivar(state, state->symbol("@outbox")));
Channel* inbox = inbox_.get();
Channel* outbox = outbox_.get();

String* response = 0;
OnStack<3> os(state, inbox, outbox, response);
@@ -352,23 +327,135 @@ namespace rubinius {
}
}

Listener::Listener(STATE, Console* console)
: InternalThread(state, "rbx.console.listener")
, console_(console)
, fsevent_(state)
, fd_(-1)
{
}

Listener::~Listener() {
close(fd_);
}

void Listener::initialize(STATE) {
fd_ = ::open(console_->console_path().c_str(),
O_CREAT | O_TRUNC | O_RDWR | O_CLOEXEC,
state->shared().config.system_console_access.value);

if(fd_ < 0) {
utilities::logger::error("%s: unable to open Console connection file",
strerror(errno));
}

// The umask setting will override our permissions for open().
if(chmod(console_->console_path().c_str(),
state->shared().config.system_console_access.value) < 0) {
utilities::logger::error("%s: unable to set mode for Console connection file",
strerror(errno));
}

FSEvent* fsevent = FSEvent::create(state);
fsevent->watch_file(state, fd_, console_->console_path().c_str());
fsevent_.set(fsevent);
}

void Listener::start_thread(STATE) {
InternalThread::start_thread(state);
}

void Listener::wakeup(STATE) {
InternalThread::wakeup(state);

if(write(fd_, "\0", 1) < 0) {
logger::error("%s: console: unable to wake listener thread", strerror(errno));
}
}

bool Listener::connection_initiated() {
struct stat st;

bool req = stat(console_->request_path().c_str(), &st) == 0 && S_ISREG(st.st_mode);
bool res = stat(console_->response_path().c_str(), &st) == 0 && S_ISREG(st.st_mode);

return req && res;
}

void Listener::run(STATE) {
while(!thread_exit_) {
Object* status = fsevent_.get()->wait_for_event(state);

if(thread_exit_) break;

if(status->nil_p()) {
utilities::logger::error("%s: console: listener: wait for event failed",
strerror(errno));
continue;
}

if(console_->connected_p()) continue;

if(connection_initiated()) {
console_->accept(state);
}
}
}

Console::Console(STATE)
: path_(std::string(state->shared().fsapi_path + "/console"))
, response_(new Response(state, this))
, request_(new Request(state, this))
: listener_(0)
, response_(0)
, request_(0)
, ruby_console_(state)
{
ruby_console_.set(server_class(state)->send(state, 0, state->symbol("new")));
console_path_ = state->shared().config.system_console_path.value;

std::ostringstream basename;
basename << state->shared().config.system_console_path.value << "-"
<< state->shared().pid;

request_path_ = basename.str() + "-request";
response_path_ = basename.str() + "-response";

listener_ = new Listener(state, this);
}

Console::~Console() {
delete request_;
delete response_;
if(listener_) delete listener_;
reset();
}

bool Console::connected_p() {
return request_ && request_->enabled_p();
}

void Console::start(STATE) {
request_->start(state);
response_->start(state);
listener_->start(state);
}

void Console::accept(STATE) {
ruby_console_.set(server_class(state)->send(state, 0, state->symbol("new")));

response_ = new Response(state, this);
request_ = new Request(state, this, response_);
}

void Console::reset() {
if(request_) {
delete request_;
request_ = 0;
}

if(response_) {
delete response_;
response_ = 0;
}

ruby_console_.set(cNil);
}

void Console::after_fork_child(STATE) {
reset();
}

Class* Console::server_class(STATE) {
74 changes: 54 additions & 20 deletions vm/console.hpp
Original file line number Diff line number Diff line change
@@ -19,12 +19,16 @@ namespace rubinius {
class String;

namespace console {
class Listener;
class Request;
class Response;

class Console {
std::string path_;
std::string console_path_;
std::string request_path_;
std::string response_path_;

Listener* listener_;
Response* response_;
Request* request_;

@@ -34,30 +38,62 @@ namespace rubinius {
Console(STATE);
virtual ~Console();

Request* request() {
return request_;
Object* ruby_console() {
return ruby_console_.get();
}

Response* response() {
return response_;
std::string& console_path() {
return console_path_;
}

Object* ruby_console() {
return ruby_console_.get();
std::string& request_path() {
return request_path_;
}

std::string& response_path() {
return response_path_;
}

bool connected_p();

void reset();

void start(STATE);
void stop(STATE);
void after_fork_child(STATE);

void accept(STATE);
Class* server_class(STATE);
};

class Listener : public InternalThread, public Lockable {
Console* console_;

TypedRoot<FSEvent*> fsevent_;

int fd_;

public:

Listener(STATE, Console* console);
virtual ~Listener();

bool connection_initiated();

void start_thread(STATE);
void initialize(STATE);
void run(STATE);
void wakeup(STATE);
};

typedef std::list<char*> RequestList;

class Response : public InternalThread, public Lockable {
Console* console_;

std::string path_;
TypedRoot<Channel*> inbox_;
TypedRoot<Channel*> outbox_;

int fd_;

RequestList* request_list_;
@@ -76,14 +112,12 @@ namespace rubinius {
void start_thread(STATE);
void run(STATE);
void wakeup(STATE);
void close_response(STATE);
void clear_requests(STATE);
void stop_thread(STATE);

void before_exec(STATE);
void after_exec(STATE);
void after_fork_child(STATE);

void close_response();
void clear_requests();

void send_request(STATE, const char* request);
void write_response(STATE, const char* response, native_int size);
};
@@ -94,27 +128,27 @@ namespace rubinius {

bool enabled_;

std::string path_;
int fd_;

TypedRoot<FSEvent*> fsevent_;

public:

Request(STATE, Console* console);
Request(STATE, Console* console, Response* response);

bool enabled_p() {
return enabled_;
}

void initialize(STATE);
void start_thread(STATE);
void run(STATE);
void wakeup(STATE);
void setup_request(STATE);
void close_request(STATE);
void stop_thread(STATE);

void before_exec(STATE);
void after_exec(STATE);
void after_fork_child(STATE);

void close_request();

char* read_request(STATE);
};
}
121 changes: 42 additions & 79 deletions vm/environment.cpp
Original file line number Diff line number Diff line change
@@ -263,32 +263,50 @@ namespace rubinius {
utilities::logger::write("command line: %s", args.str().c_str());
}

static void read_config_file(FILE* fp, ConfigParser& config_parser) {
#define RBX_CONFIG_FILE_LINE_MAX 256

char buf[RBX_CONFIG_FILE_LINE_MAX];
while(fgets(buf, RBX_CONFIG_FILE_LINE_MAX, fp)) {
int size = strlen(buf);
if(buf[size-1] == '\n') buf[size-1] = '\0';
if(strncmp(buf, "-X", 2) == 0) {
config_parser.import_line(buf + 2);
}
}
}

void Environment::load_vm_options(int argc, char**argv) {
/* We parse -X options from three sources in the following order:
*
* 1. The file .rbxrc in the current working directory.
* 2. The RBXOPT environment variable.
* 3. The command line options.
* 1. The file $HOME/.rbxconfig if $HOME is defined.
* 2. The file .rbxconfig in the current working directory.
* 3. The RBXOPT environment variable.
* 4. The command line options.
*
* This order permits environment and command line options to override
* "application" configuration. Likewise, command line options can override
* environment configuration.
*/

#define RBX_CONFIG_FILE_LINE_MAX 256
char* home = getenv("HOME");
if(home) {
std::string config_path(home);
config_path += "/.rbxconfig";

// Configuration file.
if(FILE* fp = fopen(".rbxrc", "r")) {
char buf[RBX_CONFIG_FILE_LINE_MAX];
while(fgets(buf, RBX_CONFIG_FILE_LINE_MAX, fp)) {
int size = strlen(buf);
if(buf[size-1] == '\n') buf[size-1] = '\0';
if(strncmp(buf, "-X", 2) == 0) {
config_parser.import_line(buf + 2);
}
if(FILE* fp = fopen(config_path.c_str(), "r")) {
read_config_file(fp, config_parser);
}
}

// Configuration file.
if(FILE* fp = fopen(".rbxconfig", "r")) {
read_config_file(fp, config_parser);
} else if(FILE* fp = fopen(".rbxrc", "r")) {
std::cerr << "Use of config file .rbxrc is deprecated, use .rbxconfig." << std::endl;
read_config_file(fp, config_parser);
}

// Environment.
char* rbxopt = getenv("RBXOPT");
if(rbxopt) {
@@ -339,8 +357,7 @@ namespace rubinius {
set_tmp_path();
set_username();
set_pid();

set_fsapi_path();
set_console_path();
}

void Environment::expand_config_value(std::string& cvar,
@@ -381,15 +398,14 @@ namespace rubinius {
shared->pid.assign(pid.str());
}

void Environment::set_fsapi_path() {
shared->fsapi_path.assign(config.system_fsapi_path.value);
void Environment::set_console_path() {
std::string path(config.system_console_path.value);

expand_config_value(shared->fsapi_path, "$TMPDIR", config.system_tmp);
expand_config_value(shared->fsapi_path, "$PROGRAM_NAME", RBX_PROGRAM_NAME);
expand_config_value(shared->fsapi_path, "$USER", shared->username.c_str());
expand_config_value(shared->fsapi_path, "$PID", shared->pid.c_str());
expand_config_value(path, "$TMPDIR", config.system_tmp);
expand_config_value(path, "$PROGRAM_NAME", RBX_PROGRAM_NAME);
expand_config_value(path, "$USER", shared->username.c_str());

create_fsapi(state);
config.system_console_path.value.assign(path);
}

void Environment::load_argv(int argc, char** argv) {
@@ -541,20 +557,14 @@ namespace rubinius {
delete cf;
}

void Environment::before_exec(STATE) {
remove_fsapi(state);
}

void Environment::after_exec(STATE) {
halt_lock_.init();
create_fsapi(state);
}

void Environment::after_fork_child(STATE) {
halt_lock_.init();

set_pid();
set_fsapi_path();

stop_logging(state);
start_logging(state);
@@ -564,51 +574,6 @@ namespace rubinius {
halt_lock_.init();
}

static char fsapi_path[MAXPATHLEN];

// Last resort cleanup function if normal cleanup does not occur.
static void remove_fsapi_atexit() {
char path[MAXPATHLEN];
struct dirent* entry;
DIR* dir = opendir(fsapi_path);

if(dir != NULL) {
while((entry = readdir(dir)) != NULL) {
if(entry->d_name[0] == '.') continue;

snprintf(path, MAXPATHLEN, "%s/%s", fsapi_path, entry->d_name);
unlink(path);
}

(void)closedir(dir);
}

rmdir(fsapi_path);
}

void Environment::create_fsapi(STATE) {
strncpy(fsapi_path, shared->fsapi_path.c_str(), MAXPATHLEN);

if(mkdir(shared->fsapi_path.c_str(), shared->config.system_fsapi_access) < 0) {
utilities::logger::error("%s: unable to create FSAPI path", strerror(errno));
}

// The umask setting will override our permissions for mkdir().
if(chmod(shared->fsapi_path.c_str(), shared->config.system_fsapi_access) < 0) {
utilities::logger::error("%s: unable to set mode for FSAPI path", strerror(errno));
}
}

void Environment::remove_fsapi(STATE) {
if(rmdir(shared->fsapi_path.c_str()) < 0) {
utilities::logger::error("%s: unable to remove FSAPI path", strerror(errno));
}
}

void Environment::atexit() {
remove_fsapi_atexit();
}

void Environment::halt_and_exit(STATE) {
halt(state);
exit(exit_code(state));
@@ -619,8 +584,10 @@ namespace rubinius {

state->shared().tool_broker()->shutdown(state);

if(ImmixMarker* im = state->memory()->immix_marker()) {
im->stop(state);
if(ObjectMemory* om = state->memory()) {
if(ImmixMarker* im = om->immix_marker()) {
im->stop(state);
}
}

stop_jit(state);
@@ -650,8 +617,6 @@ namespace rubinius {
}

NativeMethod::cleanup_thread(state);

remove_fsapi(state);
}

/**
@@ -871,8 +836,6 @@ namespace rubinius {
load_platform_conf(runtime);
boot_vm();

::atexit(remove_fsapi_atexit);

start_finalizer(state);

load_argv(argc_, argv_);
6 changes: 1 addition & 5 deletions vm/environment.hpp
Original file line number Diff line number Diff line change
@@ -107,12 +107,11 @@ namespace rubinius {
void set_tmp_path();
void set_username();
void set_pid();
void set_fsapi_path();
void set_console_path();
void load_tool();
void run_from_filesystem();
void boot_vm();

void before_exec(STATE);
void after_exec(STATE);
void after_fork_child(STATE);
void after_fork_exec_child(STATE);
@@ -122,9 +121,6 @@ namespace rubinius {
int exit_code(STATE);
void atexit();

void create_fsapi(STATE);
void remove_fsapi(STATE);

void start_finalizer(STATE);

void start_signals(STATE);
2 changes: 0 additions & 2 deletions vm/internal_threads.cpp
Original file line number Diff line number Diff line change
@@ -140,8 +140,6 @@ namespace rubinius {
++i) {
(*i)->before_exec(state);
}

state->shared().env()->before_exec(state);
}

void InternalThreads::after_exec(STATE) {
8 changes: 6 additions & 2 deletions vm/llvm/state.cpp
Original file line number Diff line number Diff line change
@@ -446,7 +446,7 @@ namespace rubinius {
state->set_call_frame(call_frame);

{
GCIndependent guard(state, 0);
GCIndependent guard(state, call_frame);

wait_cond.wait(wait_mutex);
}
@@ -492,7 +492,11 @@ namespace rubinius {

state->set_call_frame(call_frame);

wait_cond.wait(wait_mutex);
{
GCIndependent guard(state, call_frame);

wait_cond.wait(wait_mutex);
}

wait_mutex.unlock();
state->set_call_frame(0);
2 changes: 1 addition & 1 deletion vm/shared_state.cpp
Original file line number Diff line number Diff line change
@@ -55,7 +55,6 @@ namespace rubinius {
, config(config)
, user_variables(cp)
, llvm_state(0)
, fsapi_path("")
, username("")
, pid("")
{
@@ -242,6 +241,7 @@ namespace rubinius {
internal_threads_->init();

om->after_fork_child(state);
console_->after_fork_child(state);

state->vm()->set_run_state(ManagedThread::eIndependent);
gc_dependent(state, 0);
1 change: 0 additions & 1 deletion vm/shared_state.hpp
Original file line number Diff line number Diff line change
@@ -149,7 +149,6 @@ namespace rubinius {
ConfigParser& user_variables;
SymbolTable symbols;
LLVMState* llvm_state;
std::string fsapi_path;
std::string username;
std::string pid;
uint32_t hash_seed;
2 changes: 0 additions & 2 deletions vm/signal.cpp
Original file line number Diff line number Diff line change
@@ -360,8 +360,6 @@ namespace rubinius {
sleep(timeout);
}

signal_thread_->shared().env()->atexit();

#define RBX_ABORT_CALLSTACK_SIZE 128
void* callstack[RBX_ABORT_CALLSTACK_SIZE];
int i, frames = backtrace(callstack, RBX_ABORT_CALLSTACK_SIZE);

0 comments on commit 8e023e1

Please sign in to comment.