bsnes/nall/posix/service.hpp
Tim Allen 82293c95ae Update to v099r14 release.
byuu says:

Changelog:
- (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel
  like they were contributing enough to be worth it]
- cleaned up nall::integer,natural,real functionality
  - toInteger, toNatural, toReal for parsing strings to numbers
  - fromInteger, fromNatural, fromReal for creating strings from numbers
  - (string,Markup::Node,SQL-based-classes)::(integer,natural,real)
    left unchanged
  - template<typename T> numeral(T value, long padding, char padchar)
    -> string for print() formatting
    - deduces integer,natural,real based on T ... cast the value if you
      want to override
    - there still exists binary,octal,hex,pointer for explicit print()
      formatting
- lstring -> string_vector [but using lstring = string_vector; is
  declared]
  - would be nice to remove the using lstring eventually ... but that'd
    probably require 10,000 lines of changes >_>
- format -> string_format [no using here; format was too ambiguous]
- using integer = Integer<sizeof(int)*8>; and using natural =
  Natural<sizeof(uint)*8>; declared
  - for consistency with boolean. These three are meant for creating
    zero-initialized values implicitly (various uses)
- R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees
  up struct IO {} io; naming]
- SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {}
  (status,registers); now
  - still some CPU::Status status values ... they didn't really fit into
    IO functionality ... will have to think about this more
- SFC CPU, PPU, SMP now use step() exclusively instead of addClocks()
  calling into step()
- SFC CPU joypad1_bits, joypad2_bits were unused; killed them
- SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it
- SFC PPU OAM moved into PPU::Object; since nothing else uses it
  - the raw uint8[544] array is gone. OAM::read() constructs values from
    the OAM::Object[512] table now
  - this avoids having to determine how we want to sub-divide the two
    OAM memory sections
  - this also eliminates the OAM::synchronize() functionality
- probably more I'm forgetting

The FPS fluctuations are driving me insane. This WIP went from 128fps to
137fps. Settled on 133.5fps for the final build. But nothing I changed
should have affected performance at all. This level of fluctuation makes
it damn near impossible to know whether I'm speeding things up or slowing
things down with changes.
2016-07-01 21:50:32 +10:00

115 lines
2.8 KiB
C++

#pragma once
#include <signal.h>
namespace nall {
struct service {
inline explicit operator bool() const;
inline auto command(const string& name, const string& command) -> bool;
inline auto receive() -> string;
inline auto name() const -> string;
inline auto stop() const -> bool;
private:
shared_memory shared;
string _name;
bool _stop = false;
};
service::operator bool() const {
return (bool)shared;
}
//returns true on new service process creation (false is not necessarily an error)
auto service::command(const string& name, const string& command) -> bool {
if(!name) return false;
if(!command) return print("[{0}] usage: {service} command\n"
"commands:\n"
" status : query whether service is running\n"
" start : start service if it is not running\n"
" stop : stop service if it is running\n"
" remove : remove semaphore lock if service crashed\n"
" {value} : send custom command to service\n"
"", string_format{name}), false;
if(shared.open(name, 4096)) {
if(command == "start") {
print("[{0}] already started\n", string_format{name});
} else if(command == "status") {
print("[{0}] running\n", string_format{name});
}
if(auto data = shared.acquire()) {
if(command == "stop") print("[{0}] stopped\n", string_format{name});
memory::copy(data, command.data(), min(command.size(), 4096));
shared.release();
}
if(command == "remove") {
shared.remove();
print("[{0}] removed\n", string_format{name});
}
return false;
}
if(command == "start") {
if(shared.create(name, 4096)) {
print("[{0}] started\n", string_format{name});
auto pid = fork();
if(pid == 0) {
signal(SIGHUP, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
_name = name;
return true;
}
shared.close();
} else {
print("[{0}] start failed ({1})\n", string_format{name, strerror(errno)});
}
return false;
}
if(command == "status") {
print("[{0}] stopped\n", string_format{name});
return false;
}
return false;
}
auto service::receive() -> string {
string command;
if(shared) {
if(auto data = shared.acquire()) {
if(*data) {
command.resize(4095);
memory::copy(command.get(), data, 4095);
memory::fill(data, 4096);
}
shared.release();
if(command == "remove") {
_stop = true;
return "";
} else if(command == "start") {
return "";
} else if(command == "status") {
return "";
} else if(command == "stop") {
_stop = true;
shared.remove();
return "";
}
}
}
return command;
}
auto service::name() const -> string {
return _name;
}
auto service::stop() const -> bool {
return _stop;
}
}