mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-03 10:12:45 +02:00
Update to v094r25 release.
byuu says: Windows port should run mostly well now, although exiting fullscreen breaks the application in a really bizarre way. (clicking on the window makes it sink to background rather than come to the foreground o_O) I also need to add the doModalChange => audio.clear() thing for the accursed menu stuttering with DirectSound. I also finished porting all of the ruby drivers over to the newer API changes from nall. Since I can't compile the Linux or OS X drivers, I have no idea if there are any typos that will result in compilation errors. If so, please let me know where they're at and I'll try and fix them. If they're simple, please try and fix them on your end to test further if you can. I'm hopeful the udev crash will be gone now that nall::string checks for null char* values passed to its stringify function. Of course, it's a problem it's getting a null value in the first place, so it may not work at all. If you can compile on Linux (or by some miracle, OS X), please test each video/audio/input driver if you don't mind, to make sure there's no "compiles okay but still typos exist" bugs.
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
#ifndef NALL_HTTP_SERVER_HPP
|
||||
#define NALL_HTTP_SERVER_HPP
|
||||
|
||||
#include <poll.h>
|
||||
#include <atomic>
|
||||
|
||||
#include <nall/service.hpp>
|
||||
#include <nall/http/role.hpp>
|
||||
|
||||
|
@@ -56,13 +56,16 @@ namespace nall {
|
||||
#define PLATFORM_WINDOWS
|
||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Windows; }
|
||||
#elif defined(__APPLE__)
|
||||
#define PLATFORM_POSIX
|
||||
#define PLATFORM_MACOSX
|
||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::MacOSX; }
|
||||
#elif defined(linux) || defined(__linux__)
|
||||
#define PLATFORM_POSIX
|
||||
#define PLATFORM_LINUX
|
||||
#define PLATFORM_XORG
|
||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Linux; }
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#define PLATFORM_POSIX
|
||||
#define PLATFORM_BSD
|
||||
#define PLATFORM_XORG
|
||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::BSD; }
|
||||
|
@@ -51,6 +51,7 @@ namespace Math {
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#if defined(COMPILER_CL)
|
||||
@@ -58,17 +59,40 @@ namespace Math {
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
//fight Microsoft's ardent efforts at vendor lock-in
|
||||
|
||||
#undef interface
|
||||
#define dllexport __declspec(dllexport)
|
||||
#define MSG_NOSIGNAL 0
|
||||
|
||||
extern "C" {
|
||||
using pollfd = WSAPOLLFD;
|
||||
}
|
||||
|
||||
inline auto access(const char* path, int amode) -> int { return _waccess(nall::utf16_t(path), amode); }
|
||||
inline auto getcwd(char* buf, size_t size) -> char* { wchar_t wpath[PATH_MAX] = L""; if(!_wgetcwd(wpath, size)) return nullptr; strcpy(buf, nall::utf8_t(wpath)); return buf; }
|
||||
inline auto mkdir(const char* path, int mode) -> int { return _wmkdir(nall::utf16_t(path)); }
|
||||
inline auto poll(struct pollfd fds[], unsigned long nfds, int timeout) -> int { return WSAPoll(fds, nfds, timeout); }
|
||||
inline auto putenv(const char* value) -> int { return _wputenv(nall::utf16_t(value)); }
|
||||
inline auto realpath(const char* file_name, char* resolved_name) -> char* { wchar_t wfile_name[PATH_MAX] = L""; if(!_wfullpath(wfile_name, nall::utf16_t(file_name), PATH_MAX)) return nullptr; strcpy(resolved_name, nall::utf8_t(wfile_name)); return resolved_name; }
|
||||
inline auto rename(const char* oldname, const char* newname) -> int { return _wrename(nall::utf16_t(oldname), nall::utf16_t(newname)); }
|
||||
inline auto usleep(unsigned milliseconds) -> void { Sleep(milliseconds / 1000); }
|
||||
|
||||
namespace nall {
|
||||
//network functions take void*, not char*. this allows them to be used without casting
|
||||
|
||||
inline auto recv(int socket, void* buffer, size_t length, int flags) -> ssize_t {
|
||||
return ::recv(socket, (char*)buffer, length, flags);
|
||||
}
|
||||
|
||||
inline auto send(int socket, const void* buffer, size_t length, int flags) -> ssize_t {
|
||||
return ::send(socket, (const char*)buffer, length, flags);
|
||||
}
|
||||
|
||||
inline auto setsockopt(int socket, int level, int option_name, const void* option_value, socklen_t option_len) -> int {
|
||||
return ::setsockopt(socket, level, option_name, (const char*)option_value, option_len);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define dllexport
|
||||
#endif
|
||||
|
117
nall/posix/service.hpp
Normal file
117
nall/posix/service.hpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#ifndef NALL_POSIX_SERVICE_HPP
|
||||
#define NALL_POSIX_SERVICE_HPP
|
||||
|
||||
#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"
|
||||
"", format{name}), false;
|
||||
|
||||
if(shared.open(name, 4096)) {
|
||||
if(command == "start") {
|
||||
print("[{0}] already started\n", format{name});
|
||||
} else if(command == "status") {
|
||||
print("[{0}] running\n", format{name});
|
||||
}
|
||||
if(auto data = shared.acquire()) {
|
||||
if(command == "stop") print("[{0}] stopped\n", format{name});
|
||||
memory::copy(data, command.data(), min(command.size(), 4096));
|
||||
shared.release();
|
||||
}
|
||||
if(command == "remove") {
|
||||
shared.remove();
|
||||
print("[{0}] removed\n", format{name});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(command == "start") {
|
||||
if(shared.create(name, 4096)) {
|
||||
print("[{0}] started\n", 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", format{name, strerror(errno)});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(command == "status") {
|
||||
print("[{0}] stopped\n", 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.pointer(), 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
154
nall/posix/shared-memory.hpp
Normal file
154
nall/posix/shared-memory.hpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#ifndef NALL_POSIX_SHARED_MEMORY_HPP
|
||||
#define NALL_POSIX_SHARED_MEMORY_HPP
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
namespace nall {
|
||||
|
||||
struct shared_memory {
|
||||
shared_memory() = default;
|
||||
shared_memory(const shared_memory&) = delete;
|
||||
auto operator=(const shared_memory&) -> shared_memory& = delete;
|
||||
|
||||
~shared_memory() {
|
||||
reset();
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return _mode != mode::inactive;
|
||||
}
|
||||
|
||||
auto empty() const -> bool {
|
||||
return _mode == mode::inactive;
|
||||
}
|
||||
|
||||
auto size() const -> unsigned {
|
||||
return _size;
|
||||
}
|
||||
|
||||
auto acquired() const -> bool {
|
||||
return _acquired;
|
||||
}
|
||||
|
||||
auto acquire() -> uint8_t* {
|
||||
if(!acquired()) {
|
||||
sem_wait(_semaphore);
|
||||
_acquired = true;
|
||||
}
|
||||
return _data;
|
||||
}
|
||||
|
||||
auto release() -> void {
|
||||
if(acquired()) {
|
||||
sem_post(_semaphore);
|
||||
_acquired = false;
|
||||
}
|
||||
}
|
||||
|
||||
auto reset() -> void {
|
||||
release();
|
||||
if(_mode == mode::server) return remove();
|
||||
if(_mode == mode::client) return close();
|
||||
}
|
||||
|
||||
auto create(const string& name, unsigned size) -> bool {
|
||||
reset();
|
||||
|
||||
_name = {"/nall::", string{name}.transform("/", ":")};
|
||||
_size = size;
|
||||
|
||||
//O_CREAT | O_EXCL seems to throw ENOENT even when semaphore does not exist ...
|
||||
_semaphore = sem_open(_name, O_CREAT, 0644, 1);
|
||||
if(_semaphore == SEM_FAILED) return remove(), false;
|
||||
|
||||
_descriptor = shm_open(_name, O_CREAT | O_TRUNC | O_RDWR, 0644);
|
||||
if(_descriptor < 0) return remove(), false;
|
||||
|
||||
if(ftruncate(_descriptor, _size) != 0) return remove(), false;
|
||||
|
||||
_data = (uint8_t*)mmap(nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _descriptor, 0);
|
||||
if(_data == MAP_FAILED) return remove(), false;
|
||||
|
||||
memory::fill(_data, _size);
|
||||
|
||||
_mode = mode::server;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto remove() -> void {
|
||||
if(_data) {
|
||||
munmap(_data, _size);
|
||||
_data = nullptr;
|
||||
}
|
||||
|
||||
if(_descriptor) {
|
||||
::close(_descriptor);
|
||||
shm_unlink(_name);
|
||||
_descriptor = -1;
|
||||
}
|
||||
|
||||
if(_semaphore) {
|
||||
sem_close(_semaphore);
|
||||
sem_unlink(_name);
|
||||
_semaphore = nullptr;
|
||||
}
|
||||
|
||||
_mode = mode::inactive;
|
||||
_name = "";
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
auto open(const string& name, unsigned size) -> bool {
|
||||
reset();
|
||||
|
||||
_name = {"/nall::", string{name}.transform("/", ":")};
|
||||
_size = size;
|
||||
|
||||
_semaphore = sem_open(_name, 0, 0644);
|
||||
if(_semaphore == SEM_FAILED) return close(), false;
|
||||
|
||||
_descriptor = shm_open(_name, O_RDWR, 0644);
|
||||
if(_descriptor < 0) return close(), false;
|
||||
|
||||
_data = (uint8_t*)mmap(nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _descriptor, 0);
|
||||
if(_data == MAP_FAILED) return close(), false;
|
||||
|
||||
_mode = mode::client;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto close() -> void {
|
||||
if(_data) {
|
||||
munmap(_data, _size);
|
||||
_data = nullptr;
|
||||
}
|
||||
|
||||
if(_descriptor) {
|
||||
::close(_descriptor);
|
||||
_descriptor = -1;
|
||||
}
|
||||
|
||||
if(_semaphore) {
|
||||
sem_close(_semaphore);
|
||||
_semaphore = nullptr;
|
||||
}
|
||||
|
||||
_mode = mode::inactive;
|
||||
_name = "";
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class mode : unsigned { server, client, inactive } _mode = mode::inactive;
|
||||
string _name;
|
||||
sem_t* _semaphore = nullptr;
|
||||
signed _descriptor = -1;
|
||||
uint8_t* _data = nullptr;
|
||||
unsigned _size = 0;
|
||||
bool _acquired = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
116
nall/service.hpp
116
nall/service.hpp
@@ -3,118 +3,14 @@
|
||||
|
||||
//service model template built on top of shared-memory
|
||||
|
||||
#include <signal.h>
|
||||
#include <nall/shared-memory.hpp>
|
||||
|
||||
namespace nall {
|
||||
#if defined(PLATFORM_POSIX)
|
||||
#include <nall/posix/service.hpp>
|
||||
#endif
|
||||
|
||||
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"
|
||||
"", format{name}), false;
|
||||
|
||||
if(shared.open(name, 4096)) {
|
||||
if(command == "start") {
|
||||
print("[{0}] already started\n", format{name});
|
||||
} else if(command == "status") {
|
||||
print("[{0}] running\n", format{name});
|
||||
}
|
||||
if(auto data = shared.acquire()) {
|
||||
if(command == "stop") print("[{0}] stopped\n", format{name});
|
||||
memory::copy(data, command.data(), min(command.size(), 4096));
|
||||
shared.release();
|
||||
}
|
||||
if(command == "remove") {
|
||||
shared.remove();
|
||||
print("[{0}] removed\n", format{name});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(command == "start") {
|
||||
if(shared.create(name, 4096)) {
|
||||
print("[{0}] started\n", 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", format{name, strerror(errno)});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(command == "status") {
|
||||
print("[{0}] stopped\n", 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.pointer(), 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;
|
||||
}
|
||||
|
||||
}
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
#include <nall/windows/service.hpp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -4,154 +4,12 @@
|
||||
#include <nall/memory.hpp>
|
||||
#include <nall/string.hpp>
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <sys/mman.h>
|
||||
#if defined(PLATFORM_POSIX)
|
||||
#include <nall/posix/shared-memory.hpp>
|
||||
#endif
|
||||
|
||||
namespace nall {
|
||||
|
||||
struct shared_memory {
|
||||
shared_memory() = default;
|
||||
shared_memory(const shared_memory&) = delete;
|
||||
shared_memory& operator=(const shared_memory&) = delete;
|
||||
|
||||
~shared_memory() {
|
||||
reset();
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return _mode != mode::inactive;
|
||||
}
|
||||
|
||||
auto empty() const -> bool {
|
||||
return _mode == mode::inactive;
|
||||
}
|
||||
|
||||
auto size() const -> unsigned {
|
||||
return _size;
|
||||
}
|
||||
|
||||
auto acquired() const -> bool {
|
||||
return _acquired;
|
||||
}
|
||||
|
||||
auto acquire() -> uint8_t* {
|
||||
if(!acquired()) {
|
||||
sem_wait(_semaphore);
|
||||
_acquired = true;
|
||||
}
|
||||
return _data;
|
||||
}
|
||||
|
||||
auto release() -> void {
|
||||
if(acquired()) {
|
||||
sem_post(_semaphore);
|
||||
_acquired = false;
|
||||
}
|
||||
}
|
||||
|
||||
auto reset() -> void {
|
||||
release();
|
||||
if(_mode == mode::server) return remove();
|
||||
if(_mode == mode::client) return close();
|
||||
}
|
||||
|
||||
auto create(const string& name, unsigned size) -> bool {
|
||||
reset();
|
||||
|
||||
_name = {"/nall::", string{name}.transform("/", ":")};
|
||||
_size = size;
|
||||
|
||||
//O_CREAT | O_EXCL seems to throw ENOENT even when semaphore does not exist ...
|
||||
_semaphore = sem_open(_name, O_CREAT, 0644, 1);
|
||||
if(_semaphore == SEM_FAILED) return remove(), false;
|
||||
|
||||
_descriptor = shm_open(_name, O_CREAT | O_TRUNC | O_RDWR, 0644);
|
||||
if(_descriptor < 0) return remove(), false;
|
||||
|
||||
if(ftruncate(_descriptor, _size) != 0) return remove(), false;
|
||||
|
||||
_data = (uint8_t*)mmap(nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _descriptor, 0);
|
||||
if(_data == MAP_FAILED) return remove(), false;
|
||||
|
||||
memory::fill(_data, _size);
|
||||
|
||||
_mode = mode::server;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto remove() -> void {
|
||||
if(_data) {
|
||||
munmap(_data, _size);
|
||||
_data = nullptr;
|
||||
}
|
||||
|
||||
if(_descriptor) {
|
||||
::close(_descriptor);
|
||||
shm_unlink(_name);
|
||||
_descriptor = -1;
|
||||
}
|
||||
|
||||
if(_semaphore) {
|
||||
sem_close(_semaphore);
|
||||
sem_unlink(_name);
|
||||
_semaphore = nullptr;
|
||||
}
|
||||
|
||||
_mode = mode::inactive;
|
||||
_name = "";
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
auto open(const string& name, unsigned size) -> bool {
|
||||
reset();
|
||||
|
||||
_name = {"/nall::", string{name}.transform("/", ":")};
|
||||
_size = size;
|
||||
|
||||
_semaphore = sem_open(_name, 0, 0644);
|
||||
if(_semaphore == SEM_FAILED) return close(), false;
|
||||
|
||||
_descriptor = shm_open(_name, O_RDWR, 0644);
|
||||
if(_descriptor < 0) return close(), false;
|
||||
|
||||
_data = (uint8_t*)mmap(nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _descriptor, 0);
|
||||
if(_data == MAP_FAILED) return close(), false;
|
||||
|
||||
_mode = mode::client;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto close() -> void {
|
||||
if(_data) {
|
||||
munmap(_data, _size);
|
||||
_data = nullptr;
|
||||
}
|
||||
|
||||
if(_descriptor) {
|
||||
::close(_descriptor);
|
||||
_descriptor = -1;
|
||||
}
|
||||
|
||||
if(_semaphore) {
|
||||
sem_close(_semaphore);
|
||||
_semaphore = nullptr;
|
||||
}
|
||||
|
||||
_mode = mode::inactive;
|
||||
_name = "";
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class mode : unsigned { server, client, inactive } _mode = mode::inactive;
|
||||
string _name;
|
||||
sem_t* _semaphore = nullptr;
|
||||
signed _descriptor = -1;
|
||||
uint8_t* _data = nullptr;
|
||||
unsigned _size = 0;
|
||||
bool _acquired = false;
|
||||
};
|
||||
|
||||
}
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
#include <nall/windows/shared-memory.hpp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -80,7 +80,7 @@ struct shared_pointer {
|
||||
reset();
|
||||
}
|
||||
|
||||
shared_pointer& operator=(T* source) {
|
||||
auto operator=(T* source) -> shared_pointer& {
|
||||
reset();
|
||||
if(source) {
|
||||
manager = new shared_pointer_manager((void*)source);
|
||||
@@ -89,7 +89,7 @@ struct shared_pointer {
|
||||
return *this;
|
||||
}
|
||||
|
||||
shared_pointer& operator=(const shared_pointer& source) {
|
||||
auto operator=(const shared_pointer& source) -> shared_pointer& {
|
||||
if(this != &source) {
|
||||
reset();
|
||||
if((bool)source) {
|
||||
@@ -100,7 +100,7 @@ struct shared_pointer {
|
||||
return *this;
|
||||
}
|
||||
|
||||
shared_pointer& operator=(shared_pointer&& source) {
|
||||
auto operator=(shared_pointer&& source) -> shared_pointer& {
|
||||
if(this != &source) {
|
||||
reset();
|
||||
manager = source.manager;
|
||||
@@ -110,7 +110,7 @@ struct shared_pointer {
|
||||
}
|
||||
|
||||
template<typename U, typename = enable_if<is_compatible<U>>>
|
||||
shared_pointer& operator=(const shared_pointer<U>& source) {
|
||||
auto operator=(const shared_pointer<U>& source) -> shared_pointer& {
|
||||
if((uintptr_t)this != (uintptr_t)&source) {
|
||||
reset();
|
||||
if((bool)source) {
|
||||
@@ -122,7 +122,7 @@ struct shared_pointer {
|
||||
}
|
||||
|
||||
template<typename U, typename = enable_if<is_compatible<U>>>
|
||||
shared_pointer& operator=(shared_pointer&& source) {
|
||||
auto operator=(shared_pointer&& source) -> shared_pointer& {
|
||||
if((uintptr_t)this != (uintptr_t)&source) {
|
||||
reset();
|
||||
manager = source.manager;
|
||||
@@ -132,7 +132,7 @@ struct shared_pointer {
|
||||
}
|
||||
|
||||
template<typename U, typename = enable_if<is_compatible<U>>>
|
||||
shared_pointer& operator=(const shared_pointer_weak<U>& source) {
|
||||
auto operator=(const shared_pointer_weak<U>& source) -> shared_pointer& {
|
||||
reset();
|
||||
if((bool)source) {
|
||||
manager = source.manager;
|
||||
@@ -141,32 +141,32 @@ struct shared_pointer {
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* data() {
|
||||
auto data() -> T* {
|
||||
if(manager) return (T*)manager->pointer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const T* data() const {
|
||||
auto data() const -> const T* {
|
||||
if(manager) return (T*)manager->pointer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
T* operator->() { return data(); }
|
||||
const T* operator->() const { return data(); }
|
||||
auto operator->() -> T* { return data(); }
|
||||
auto operator->() const -> const T* { return data(); }
|
||||
|
||||
T& operator*() { return *data(); }
|
||||
const T& operator*() const { return *data(); }
|
||||
auto operator*() -> T& { return *data(); }
|
||||
auto operator*() const -> const T& { return *data(); }
|
||||
|
||||
T& operator()() { return *data(); }
|
||||
const T& operator()() const { return *data(); }
|
||||
auto operator()() -> T& { return *data(); }
|
||||
auto operator()() const -> const T& { return *data(); }
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const shared_pointer<U>& source) const {
|
||||
auto operator==(const shared_pointer<U>& source) const -> bool {
|
||||
return manager == source.manager;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator!=(const shared_pointer<U>& source) const {
|
||||
auto operator!=(const shared_pointer<U>& source) const -> bool {
|
||||
return manager != source.manager;
|
||||
}
|
||||
|
||||
@@ -174,15 +174,15 @@ struct shared_pointer {
|
||||
return !empty();
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
auto empty() const -> bool {
|
||||
return !manager || !manager->strong;
|
||||
}
|
||||
|
||||
bool unique() const {
|
||||
auto unique() const -> bool {
|
||||
return manager && manager->strong == 1;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
auto reset() -> void {
|
||||
if(manager && manager->strong) {
|
||||
//pointer may contain weak references; if strong==0 it may destroy manager
|
||||
//as such, we must destroy strong before decrementing it to zero
|
||||
@@ -204,7 +204,7 @@ struct shared_pointer {
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
shared_pointer<U> cast() {
|
||||
auto cast() -> shared_pointer<U> {
|
||||
if(auto pointer = dynamic_cast<U*>(data())) {
|
||||
return {*this, pointer};
|
||||
}
|
||||
@@ -224,7 +224,7 @@ struct shared_pointer_weak {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
shared_pointer_weak& operator=(const shared_pointer<T>& source) {
|
||||
auto operator=(const shared_pointer<T>& source) -> shared_pointer_weak& {
|
||||
reset();
|
||||
if(manager = source.manager) manager->weak++;
|
||||
return *this;
|
||||
@@ -234,19 +234,27 @@ struct shared_pointer_weak {
|
||||
reset();
|
||||
}
|
||||
|
||||
auto operator==(const shared_pointer_weak& source) const -> bool {
|
||||
return manager == source.manager;
|
||||
}
|
||||
|
||||
auto operator!=(const shared_pointer_weak& source) const -> bool {
|
||||
return manager != source.manager;
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return !empty();
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
auto empty() const -> bool {
|
||||
return !manager || !manager->strong;
|
||||
}
|
||||
|
||||
shared_pointer<T> acquire() const {
|
||||
auto acquire() const -> shared_pointer<T> {
|
||||
return shared_pointer<T>(*this);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
auto reset() -> void {
|
||||
if(manager && --manager->weak == 0) {
|
||||
if(manager->strong == 0) {
|
||||
delete manager;
|
||||
|
16
nall/windows/service.hpp
Normal file
16
nall/windows/service.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef NALL_WINDOWS_SERVICE_HPP
|
||||
#define NALL_WINDOWS_SERVICE_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
struct service {
|
||||
explicit operator bool() const { return false; }
|
||||
auto command(const string& name, const string& command) -> bool { return false; }
|
||||
auto receive() -> string { return ""; }
|
||||
auto name() const -> string { return ""; }
|
||||
auto stop() const -> bool { return false; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
30
nall/windows/shared-memory.hpp
Normal file
30
nall/windows/shared-memory.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef NALL_WINDOWS_SHARED_MEMORY_HPP
|
||||
#define NALL_WINDOWS_SHARED_MEMORY_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
struct shared_memory {
|
||||
shared_memory() = default;
|
||||
shared_memory(const shared_memory&) = delete;
|
||||
auto operator=(const shared_memory&) -> shared_memory& = delete;
|
||||
|
||||
~shared_memory() {
|
||||
reset();
|
||||
}
|
||||
|
||||
explicit operator bool() const { return false; }
|
||||
auto empty() const -> bool { return true; }
|
||||
auto size() const -> unsigned { return 0; }
|
||||
auto acquired() const -> bool { return false; }
|
||||
auto acquire() -> uint8_t* { return nullptr; }
|
||||
auto release() -> void {}
|
||||
auto reset() -> void {}
|
||||
auto create(const string& name, unsigned size) -> bool { return false; }
|
||||
auto remove() -> void {}
|
||||
auto open(const string& name, unsigned size) -> bool { return false; }
|
||||
auto close() -> void {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user