Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F126006
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
35 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/util/funcs.cpp b/util/funcs.cpp
index bcd20c28..6fd9d786 100644
--- a/util/funcs.cpp
+++ b/util/funcs.cpp
@@ -1,306 +1,311 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#endif
#include "funcs.h"
#include "globals.h"
#include "debug.h"
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
#include "file-system.h"
#include "bitmap.h"
#include "trans-bitmap.h"
#include "font.h"
#include "init.h"
#include <sstream>
+#include "file-system.h"
#ifndef USE_ALLEGRO
/* FIXME: move this to the filesystem module */
#include "sfl/sfl.h"
#include "sfl/sflfile.h"
#endif
#ifndef WINDOWS
#include <unistd.h>
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
using namespace std;
/* remove this once cmake and scons properly set DATA_PATH */
#ifndef DATA_PATH
#define DATA_PATH "data"
#endif
/* the build system should define DATA_PATH */
static string dataPath = DATA_PATH;
const double Util::pi = 3.14159265358979323846;
double Util::radians(double degree){
return degree * pi / 180.0;
}
/*
inline int rnd( int q ){
if ( q <= 0 ) return 0;
return (int)( rand() % q );
}
*/
int Util::max(int a, int b){
if (a>b){
return a;
}
return b;
}
/*
int Util::min(int a, int b){
if (a<b){
return a;
}
return b;
}
*/
int Util::clamp(int value, int min, int max){
return Util::min(Util::max(value, min), max);
}
int Util::rnd( int q, int min, int range ){
return q - min + rnd( range );
}
int Util::rnd( int min, int max ){
return rnd( max - min ) + min;
}
/* sleep for `x' milliseconds */
void Util::rest( int x ){
#ifdef USE_ALLEGRO
::rest(x);
#endif
#ifdef USE_SDL
SDL_Delay(x);
#endif
#ifdef USE_ALLEGRO5
al_rest((double) x / 1000.0);
#endif
}
void Util::restSeconds(double x){
Util::rest((int)(x * 1000));
}
bool Util::checkVersion(int version){
if (version == Global::getVersion()){
return true;
}
/* when an incompatible version is made, add a check here, like
* version < getVersion(3, 5)
* would mean any client below version 3.5 is incompatible.
*
* assume versions of client's greater than ourself is compatible, but
* this may not be true. There is no way to check this.
*/
if (version < 0){
return false;
}
return true;
}
void Util::setDataPath( const string & str ){
dataPath = str;
}
Filesystem::AbsolutePath Util::getDataPath2(){
return Filesystem::AbsolutePath(dataPath + "/");
}
+/* FIXME: remove this method */
bool Util::exists( const string & file ){
+ return Storage::instance().exists(Filesystem::AbsolutePath(file));
+/*
#ifdef USE_ALLEGRO
return ::exists(file.c_str()) != 0;
#else
return file_exists(file.c_str());
#endif
+*/
}
/*
vector<Filesystem::AbsolutePath> Util::getFiles(const Filesystem::AbsolutePath & dataPath, const string & find){
return Filesystem::getFiles(dataPath, find);
}
*/
string Util::trim(const std::string & str){
string s;
size_t startpos = str.find_first_not_of(" \t");
size_t endpos = str.find_last_not_of(" \t");
// if all spaces or empty return an empty string
if ((string::npos == startpos) ||
(string::npos == endpos)){
return "";
} else {
return str.substr(startpos, endpos-startpos+1);
}
return str;
}
/* makes the first letter of a string upper case */
string Util::upcase(std::string str){
if ( str.length() > 0 && (str[0] >= 'a' && str[0] <= 'z') ){
str[0] = str[0] - 'a' + 'A';
}
return str;
}
static int lowerCase(int c){
return tolower(c);
}
static int upperCase(int c){
return toupper(c);
}
string Util::upperCaseAll(std::string str){
std::transform(str.begin(), str.end(), str.begin(), upperCase);
return str;
}
string Util::lowerCaseAll(std::string str){
std::transform(str.begin(), str.end(), str.begin(), lowerCase);
/*
for (unsigned int i = 0; i < str.length(); i++){
if (str[0] >= 'A' && str[0] <= 'Z'){
str[0] = str[0] - 'A' + 'a';
}
}
*/
return str;
}
/*Gets the minimum of three values*/
static int minimum(int a,int b,int c){
int min=a;
if(b<min)
min=b;
if(c<min)
min=c;
return min;
}
/* Compute levenshtein distance between s and t
* from: http://www.merriampark.com/ldc.htm
*/
static int levenshtein_distance(const char *s, const char *t){
//Step 1
int k,i,j,n,m,cost,distance;
int * d;
n=strlen(s);
m=strlen(t);
if(n!=0&&m!=0){
d = (int*) malloc((sizeof(int))*(m+1)*(n+1));
m++;
n++;
//Step 2
for(k=0;k<n;k++)
d[k]=k;
for(k=0;k<m;k++)
d[k*n]=k;
//Step 3 and 4
for(i=1;i<n;i++)
for(j=1;j<m;j++)
{
//Step 5
if(s[i-1]==t[j-1])
cost=0;
else
cost=1;
//Step 6
d[j*n+i]=minimum(d[(j-1)*n+i]+1,d[j*n+i-1]+1,d[(j-1)*n+i-1]+cost);
}
distance=d[n*m-1];
free(d);
return distance;
} else {
return -1; //a negative return value means that one or both strings are empty.
}
}
int Util::levenshtein(const std::string & str1, const std::string & str2){
return levenshtein_distance(str1.c_str(), str2.c_str());
}
void Util::limitPrintf(char * buffer, int size, const char * format, va_list args){
#ifdef USE_ALLEGRO
uvszprintf(buffer, size, format, args);
#else
vsnprintf(buffer, size, format, args);
#endif
}
#ifndef WINDOWS
int Util::getPipe(int files[2]){
#ifdef PS3
return 0;
#else
return pipe(files);
#endif
}
#endif
void Util::showError(const Graphics::Bitmap & screen, const Exception::Base & exception, const string & info){
screen.BlitFromScreen(0, 0);
Graphics::Bitmap error(screen.getWidth() - 100, screen.getHeight() - 100);
error.fill(Graphics::darken(Graphics::makeColor(160, 0, 0), 3));
error.border(1, 2, Graphics::makeColor(240, 0, 0));
const Font & font = Font::getFont(Global::DEFAULT_FONT, 17, 17);
int y = 10;
std::ostringstream out;
out << info;
out << " " << exception.getTrace();
font.printfWrap(10, 10, Graphics::makeColor(240, 240, 240), error, error.getWidth() - 20, out.str(), 0);
Global::debug(0) << out.str() << std::endl;
Graphics::Bitmap::transBlender(0, 0, 0, 220);
error.translucent().draw(50, 50, screen);
screen.BlitToScreen();
}
void Util::showError(const Exception::Base & exception, const std::string & info){
Graphics::Bitmap screen(GFX_X, GFX_Y);
showError(screen, exception, info);
}
string Util::niceSize(unsigned long size){
const char sizes[] = {'b', 'k', 'm', 'g', 't'};
double real = size;
for (unsigned int i = 0; i < sizeof(sizes) / sizeof(const char); i++){
if (real > 1024){
real /= 1024.0;
} else {
ostringstream in;
in << real << sizes[i];
return in.str();
}
}
ostringstream in;
in << real << "t";
return in.str();
}
diff --git a/util/nacl/module.cpp b/util/nacl/module.cpp
index 4dc4b097..06840dd2 100644
--- a/util/nacl/module.cpp
+++ b/util/nacl/module.cpp
@@ -1,130 +1,127 @@
#ifdef NACL
/* talks to chrome via the nacl stuff */
#include <ppapi/cpp/instance.h>
#include <ppapi/cpp/module.h>
#include <ppapi/cpp/var.h>
#include <ppapi/cpp/dev/scriptable_object_deprecated.h>
#include <SDL/SDL.h>
#include <SDL/SDL_nacl.h>
#include <string>
#include "../../main.h"
#include "network-system.h"
#include "../funcs.h"
namespace nacl{
class PaintownScript: public pp::deprecated::ScriptableObject {
public:
virtual bool HasMethod(const pp::Var& method, pp::Var* exception);
virtual pp::Var Call(const pp::Var& method, const std::vector<pp::Var>& args,pp::Var* exception);
};
class PaintownInstance : public pp::Instance {
public:
explicit PaintownInstance(PP_Instance instance, pp::Core * core):
pp::Instance(instance),
core(core){
the_instance = this;
}
virtual ~PaintownInstance() {}
static PaintownInstance * the_instance;
pp::Core * core;
static int launch(void * arg){
int argc = 1;
char * argv[1] = {"paintown"};
Global::debug(0) << "Run paintown main" << std::endl;
paintown_main(argc, argv);
return 0;
}
bool HandleInputEvent(const PP_InputEvent& event){
SDL_NACL_PushEvent(&event);
return true;
}
/* set up the viewport and run the game as usual */
void run(){
Nacl::NetworkSystem * system = new Nacl::NetworkSystem(the_instance, core);
Storage::setInstance(system);
SDL_NACL_SetInstance(pp_instance(), 640, 480);
int ok = SDL_Init(SDL_INIT_VIDEO |
SDL_INIT_AUDIO |
SDL_INIT_TIMER |
SDL_INIT_JOYSTICK |
SDL_INIT_NOPARACHUTE);
Global::debug(0) << "SDL Init: " << ok << std::endl;
- // Util::setDataPath("http://localhost:5103/data/");
Util::Thread::Id thread;
Util::Thread::createThread(&thread, NULL, (Util::Thread::ThreadFunction) launch, NULL);
Global::debug(0) << "Running thread " << thread << std::endl;
- // Global::debug(0) << "Run thread " << Util::Thread::createThread(&thread, NULL, launch, NULL) << std::endl;
- // system->run();
}
virtual pp::Var GetInstanceObject(){
PaintownScript * object = new PaintownScript();
return pp::Var(this, object);
}
/* when the browser does paintownModule.postMessage('run') this will
* get executed.
*/
virtual void HandleMessage(const pp::Var& var_message){
if (!var_message.is_string()){
return;
}
std::string message = var_message.AsString();
if (message == "run"){
run();
}
}
};
PaintownInstance * PaintownInstance::the_instance;
bool PaintownScript::HasMethod(const pp::Var& method, pp::Var* exception){
if (!method.is_string()){
return false;
}
std::string name = method.AsString();
if (name == "run"){
return true;
}
return false;
}
pp::Var PaintownScript::Call(const pp::Var& method, const std::vector<pp::Var>& args,pp::Var* exception){
if (!method.is_string()){
return false;
}
std::string name = method.AsString();
if (name == "run"){
PaintownInstance::the_instance->run();
}
return pp::Var();
}
class PaintownModule : public pp::Module {
public:
PaintownModule() : pp::Module() {}
virtual ~PaintownModule() {}
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new PaintownInstance(instance, core());
}
};
}
namespace pp{
Module * CreateModule(){
return new nacl::PaintownModule();
}
}
#endif
diff --git a/util/nacl/network-system.cpp b/util/nacl/network-system.cpp
index 5fbc1220..2b425320 100644
--- a/util/nacl/network-system.cpp
+++ b/util/nacl/network-system.cpp
@@ -1,824 +1,782 @@
#ifdef NACL
/* documentation for ppapi
* http://code.google.com/chrome/nativeclient/docs/reference/peppercpp/inherits.html
*/
/* issues with getting data
* 1. the function that starts the game is called from the main chrome thread
* which starts from a javascript call to module.PostMessage('run').
* ...
*
*/
#include <unistd.h>
#include <errno.h>
#include "network-system.h"
#include "../funcs.h"
#include "../debug.h"
#include <ppapi/c/pp_errors.h>
#include <ppapi/cpp/url_loader.h>
#include <ppapi/cpp/url_request_info.h>
#include <ppapi/cpp/url_response_info.h>
#include <ppapi/c/ppb_url_request_info.h>
#include <ppapi/cpp/completion_callback.h>
using std::string;
using std::map;
namespace Nacl{
static const char * CONTEXT = "nacl";
typedef Path::AbsolutePath AbsolutePath;
typedef Path::RelativePath RelativePath;
enum RequestType{
Exists
};
struct Request{
RequestType type;
AbsolutePath absolute;
RelativePath relative;
bool complete;
bool success;
};
Request operation;
struct NaclRequest{
virtual ~NaclRequest(){
}
virtual void start() = 0;
};
struct NaclRequestOpen: public NaclRequest {
NaclRequestOpen(pp::Instance * instance, const string & url, Manager * manager):
request(instance),
loader(instance),
url(url),
manager(manager){
request.SetURL(url);
request.SetMethod("GET");
// request.SetProperty(PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS, pp::Var((bool) PP_TRUE));
}
void start(){
Global::debug(1) << "Request open for url " << url << std::endl;
pp::CompletionCallback callback(&NaclRequestOpen::onFinish, this);
int32_t ok = loader.Open(request, callback);
Global::debug(1) << "Open " << ok << std::endl;
if (ok != PP_OK_COMPLETIONPENDING){
// Global::debug(0) << "Call on main thread" << std::endl;
// core->CallOnMainThread(0, callback, ok);
callback.Run(ok);
}
// Global::debug(1) << "Callback running" << std::endl;
}
static void onFinish(void * me, int32_t result){
NaclRequestOpen * self = (NaclRequestOpen*) me;
self->finish(result);
}
void finish(int32_t result);
pp::URLRequestInfo request;
pp::URLLoader loader;
string url;
Manager * manager;
};
struct NaclRequestRead: public NaclRequest {
NaclRequestRead(pp::URLLoader & loader, Manager * manager, void * buffer, int read):
loader(loader),
manager(manager),
buffer(buffer),
read(read){
}
void start(){
pp::CompletionCallback callback(&NaclRequestRead::onFinish, this);
int32_t ok = loader.ReadResponseBody(buffer, read, callback);
Global::debug(1) << "Read " << ok << std::endl;
if (ok != PP_OK_COMPLETIONPENDING){
// Global::debug(0) << "Call on main thread" << std::endl;
// core->CallOnMainThread(0, callback, ok);
callback.Run(ok);
}
Global::debug(1) << "Callback running" << std::endl;
}
static void onFinish(void * me, int32_t result){
NaclRequestRead * self = (NaclRequestRead*) me;
self->finish(result);
}
void finish(int32_t result);
pp::URLLoader loader;
Manager * manager;
void * buffer;
int read;
};
class FileHandle{
public:
FileHandle(const Util::ReferenceCount<NaclRequestOpen> & open):
open(open),
buffer(NULL){
}
~FileHandle(){
delete[] buffer;
}
pp::URLLoader & getLoader(){
return open->loader;
}
class Reader{
public:
static const int PAGE_SIZE = 1024 * 32;
struct Page{
Page():
buffer(NULL),
size(0),
next(NULL){
buffer = new char[PAGE_SIZE];
}
char * buffer;
int size;
Page * next;
~Page(){
delete[] buffer;
delete next;
}
};
Reader(pp::CompletionCallback finish, pp::URLLoader & loader, FileHandle * handle, pp::Core * core):
finish(finish),
loader(loader),
handle(handle),
core(core),
tries(0){
current = &page;
}
int getSize(){
Page * use = &page;
int total = 0;
while (use != NULL){
total += use->size;
use = use->next;
}
return total;
}
void copy(char * buffer){
Page * use = &page;
while (use != NULL){
memcpy(buffer, use->buffer, use->size);
buffer += use->size;
use = use->next;
}
}
void read(){
pp::CompletionCallback callback(&Reader::onRead, this);
if (current->size == PAGE_SIZE){
Page * next = new Page();
current->next = next;
current = next;
}
int32_t ok = loader.ReadResponseBody(current->buffer + current->size, PAGE_SIZE - current->size, callback);
if (ok != PP_OK_COMPLETIONPENDING){
callback.Run(ok);
}
}
static void onRead(void * self, int32_t result){
Reader * reader = (Reader*) self;
reader->didRead(result);
}
void didRead(int32_t result){
Global::debug(1) << "Read " << result << " bytes" << std::endl;
current->size += result;
if (result > 0){
tries = 0;
read();
} else {
if (tries >= 2){
handle->readDone(this);
} else {
tries += 1;
pp::CompletionCallback callback(&Reader::doRead, this);
core->CallOnMainThread(50, callback, 0);
}
}
}
static void doRead(void * self, int32_t result){
Reader * reader = (Reader*) self;
reader->read();
}
pp::CompletionCallback finish;
pp::URLLoader & loader;
Page page;
Page * current;
FileHandle * handle;
pp::Core * core;
int tries;
};
void readAll(pp::CompletionCallback finish, pp::Core * core){
reader = new Reader(finish, open->loader, this, core);
reader->read();
}
void readDone(Reader * reader){
length = reader->getSize();
Global::debug(1) << "Done reading, got " << length << " bytes" << std::endl;
position = 0;
buffer = new char[length];
reader->copy(buffer);
reader->finish.Run(0);
}
int read(void * buffer, size_t count){
size_t bytes = position + count < length ? count : (length - position);
memcpy(buffer, this->buffer + position, bytes);
position += bytes;
return bytes;
}
off_t seek(off_t offset, int whence){
switch (whence){
case SEEK_SET: {
position = offset;
break;
}
case SEEK_CUR: {
position += offset;
break;
}
case SEEK_END: {
position = length - offset;
break;
}
}
return position;
}
Util::ReferenceCount<NaclRequestOpen> open;
off_t position;
off_t length;
char * buffer;
Util::ReferenceCount<Reader> reader;
};
class Manager{
public:
Manager(pp::Instance * instance, pp::Core * core):
instance(instance),
core(core),
factory(this){
next = 2;
}
pp::Instance * instance;
pp::Core * core;
Util::ReferenceCount<NaclRequest> request;
pp::CompletionCallbackFactory<Manager> factory;
map<int, Util::ReferenceCount<FileHandle> > fileTable;
int next;
struct OpenFileData{
const char * path;
int file;
};
struct ReadFileData{
int file;
void * buffer;
/* how much to read */
int count;
/* how much was read */
int read;
};
struct CloseFileData{
int fd;
};
OpenFileData openFileData;
ReadFileData readFileData;
CloseFileData closeFileData;
Util::Thread::LockObject lock;
volatile bool done;
int openFile(const char * path){
Global::debug(1, CONTEXT) << "open " << path << std::endl;
Util::Thread::ScopedLock scoped(lock);
done = false;
openFileData.path = path;
openFileData.file = -1;
pp::CompletionCallback callback(&Manager::doOpenFile, this);
core->CallOnMainThread(0, callback, 0);
lock.wait(done);
return openFileData.file;
}
bool exists(const string & path){
Global::debug(1, CONTEXT) << "exists " << path << std::endl;
Util::Thread::ScopedLock scoped(lock);
done = false;
openFileData.path = path.c_str();
openFileData.file = -1;
pp::CompletionCallback callback(&Manager::doOpenFile, this);
core->CallOnMainThread(0, callback, 0);
lock.wait(done);
return openFileData.file != -1;
}
off_t lseek(int fd, off_t offset, int whence){
Global::debug(2, CONTEXT) << "seek fd " << fd << " offset " << offset << " whence " << whence << std::endl;
Util::Thread::ScopedLock scoped(lock);
if (fileTable.find(fd) == fileTable.end()){
return -1;
}
Util::ReferenceCount<FileHandle> handle = fileTable[fd];
return handle->seek(offset, whence);
}
int close(int fd){
Util::Thread::ScopedLock scoped(lock);
if (fileTable.find(fd) == fileTable.end()){
return -1;
/* set errno to EBADF */
}
done = false;
closeFileData.fd = fd;
pp::CompletionCallback callback(&Manager::doCloseFile, this);
core->CallOnMainThread(0, callback, 0);
lock.wait(done);
return 0;
}
static void doCloseFile(void * self, int32_t result){
Manager * manager = (Manager*) self;
manager->continueCloseFile();
}
/* the destructor for the NaclRequestOpen has to occur in the main thread */
void continueCloseFile(){
fileTable.erase(fileTable.find(closeFileData.fd));
requestComplete();
}
ssize_t readFile(int fd, void * buffer, size_t count){
Util::Thread::ScopedLock scoped(lock);
if (fileTable.find(fd) == fileTable.end()){
return EBADF;
}
/* dont need to sleep on a condition variable because we are
* in the game thread.
*/
Util::ReferenceCount<FileHandle> handle = fileTable[fd];
return handle->read(buffer, count);
/*
done = false;
readFileData.file = fd;
readFileData.buffer = buffer;
readFileData.count = count;
readFileData.read = 0;
pp::CompletionCallback callback(&Manager::doReadFile, this);
core->CallOnMainThread(0, callback, 0);
lock.wait(done);
return readFileData.read;
*/
}
static void doReadFile(void * self, int32_t result){
Manager * manager = (Manager*) self;
manager->continueReadFile();
}
void continueReadFile(){
/* hack to get the open request.. */
Util::ReferenceCount<FileHandle> open = fileTable[readFileData.file];
request = new NaclRequestRead(open->getLoader(), this, readFileData.buffer, readFileData.count);
request->start();
}
/* called by the main thread */
static void doOpenFile(void * self, int32_t result){
Manager * manager = (Manager*) self;
manager->continueOpenFile();
}
void continueOpenFile(){
request = new NaclRequestOpen(instance, openFileData.path, this);
request->start();
}
int nextFileDescriptor(){
int n = next;
next += 1;
return n;
}
void requestComplete(){
/* delete the reference counted request object in the main thread */
request = NULL;
lock.lockAndSignal(done, true);
}
void success(NaclRequestOpen & open){
pp::URLResponseInfo info = open.loader.GetResponseInfo();
if (info.GetStatusCode() == 200){
Global::debug(1) << "Opened file" << std::endl;
/*
int64_t received = 0;
int64_t total = 0;
if (open.loader.GetDownloadProgress(&received, &total)){
Global::debug(0) << "Downloaded " << received << " total " << total << std::endl;
}
*/
openFileData.file = nextFileDescriptor();
fileTable[openFileData.file] = new FileHandle(request.convert<NaclRequestOpen>());
readEntireFile(fileTable[openFileData.file]);
} else {
Global::debug(1) << "Could not open file" << std::endl;
openFileData.file = -1;
requestComplete();
}
}
void readEntireFile(Util::ReferenceCount<FileHandle> & file){
pp::CompletionCallback callback(&Manager::completeRead, this);
file->readAll(callback, core);
}
static void completeRead(void * self, int32_t result){
Manager * manager = (Manager*) self;
manager->requestComplete();
}
void failure(NaclRequestOpen & open){
openFileData.file = -1;
requestComplete();
}
void success(NaclRequestRead & request, int read){
readFileData.read = read;
requestComplete();
}
};
void NaclRequestOpen::finish(int32_t result){
if (result == 0){
manager->success(*this);
} else {
manager->failure(*this);
}
}
void NaclRequestRead::finish(int32_t result){
manager->success(*this, result);
}
NetworkSystem::NetworkSystem(pp::Instance * instance, pp::Core * core):
instance(instance),
manager(new Manager(instance, core)){
}
/* TODO */
NetworkSystem::~NetworkSystem(){
}
/* TODO */
AbsolutePath NetworkSystem::find(const RelativePath & path){
- return Util::getDataPath2().join(path);
+ AbsolutePath all = Util::getDataPath2().join(path);
+ if (exists(all)){
+ return all;
+ }
+ throw Storage::NotFound(__FILE__, __LINE__, path.path());
}
/* TODO */
RelativePath NetworkSystem::cleanse(const AbsolutePath & path){
return RelativePath();
}
bool NetworkSystem::exists(const RelativePath & path){
try{
AbsolutePath absolute = find(path);
return true;
} catch (const Storage::NotFound & found){
return false;
}
}
/*
class Handler{
public:
Handler(pp::Instance * instance, const AbsolutePath & path, NetworkSystem * system):
request(instance),
loader(instance),
factory(this),
http(false),
system(system){
request.SetURL(path.path());
request.SetMethod("GET");
}
virtual void start(){
pp::CompletionCallback callback = factory.NewCallback(&Handler::OnOpen);
int32_t ok = loader.Open(request, callback);
Global::debug(0) << "Open " << ok << std::endl;
if (ok != PP_OK_COMPLETIONPENDING){
callback.Run(ok);
}
Global::debug(0) << "Callback running" << std::endl;
}
virtual void OnOpen(int32_t ok){
Global::debug(0) << "Opened! " << ok << std::endl;
system->run2();
}
pp::URLRequestInfo request;
pp::URLLoader loader;
pp::CompletionCallbackFactory<Handler> factory;
volatile bool http;
NetworkSystem * system;
};
*/
/*
void NetworkSystem::run(){
// manager->run();
Util::Thread::Id thread;
Util::Thread::createThread(&thread, NULL, &Manager::run, manager);
// manager->run();
}
*/
bool NetworkSystem::exists(const AbsolutePath & path){
- /*
- Global::debug(0) << "Checking for " << path.path() << std::endl;
- pp::CompletionCallback::Block blocking;
- pp::CompletionCallback callback(blocking);
- pp::URLRequestInfo request(instance);
- pp::URLLoader loader(instance);
- string url = serverPath + path.path();
- Global::debug(0) << "Url: " << url << std::endl;
- // request.SetURL(serverPath + path.path());
- request.SetURL("/" + path.path());
- request.SetMethod("GT");
- int32_t ok = loader.Open(request, callback);
- Global::debug(0) << "Ok: " << ok << std::endl;
- if (ok == PP_OK){
- return true;
- } else {
- return false;
- }
- */
-
+ Util::Thread::ScopedLock scoped(lock);
return manager->exists(path.path());
-
-#if 0
- Global::debug(0) << "Getting portal lock" << std::endl;
- if (portal.acquire() != 0){
- Global::debug(0) << "Lock failed!" << std::endl;
- }
- /*
- Global::debug(0) << "Getting portal lock again" << std::endl;
- if (portal.acquire() != 0){
- Global::debug(0) << "Lock failed again!" << std::endl;
- }
- Global::debug(0) << "Somehow got the portal lock twice??" << std::endl;
- */
- operation.type = Exists;
- operation.absolute = path;
- operation.complete = false;
- operation.success = false;
- Global::debug(0) << "Request open" << std::endl;
- run();
- // portal.signal();
- Global::debug(0) << "Waiting on portal" << std::endl;
- portal.wait(operation.complete);
- portal.release();
- Global::debug(0) << "Request open complete" << std::endl;
-
- return operation.success;
- /*
- Handler handler(instance, path);
- handler.start();
- handler.wait();
- return false;
- */
-#endif
}
/* TODO */
std::vector<AbsolutePath> NetworkSystem::getFilesRecursive(const AbsolutePath & dataPath, const std::string & find, bool caseInsensitive){
std::vector<AbsolutePath> paths;
return paths;
}
-/* TODO */
std::vector<AbsolutePath> NetworkSystem::getFiles(const AbsolutePath & dataPath, const std::string & find, bool caseInsensitive){
+
std::vector<AbsolutePath> paths;
+ paths.push_back(dataPath.join(RelativePath("akuma")));
+ paths.push_back(dataPath.join(RelativePath("kagetsura")));
return paths;
}
/* TODO */
AbsolutePath NetworkSystem::configFile(){
return AbsolutePath("paintownrc");
}
/* TODO */
AbsolutePath NetworkSystem::userDirectory(){
return AbsolutePath("paintownrc");
}
/* TODO */
std::vector<AbsolutePath> NetworkSystem::findDirectories(const RelativePath & path){
return std::vector<AbsolutePath>();
}
/* TODO */
AbsolutePath NetworkSystem::findInsensitive(const RelativePath & path){
return AbsolutePath();
}
/* TODO */
AbsolutePath NetworkSystem::lookupInsensitive(const AbsolutePath & directory, const RelativePath & path){
return AbsolutePath();
}
int NetworkSystem::libcOpen(const char * path, int mode, int params){
+ Util::Thread::ScopedLock scoped(lock);
return manager->openFile(path);
}
ssize_t NetworkSystem::libcRead(int fd, void * buf, size_t count){
+ Util::Thread::ScopedLock scoped(lock);
return manager->readFile(fd, buf, count);
}
int NetworkSystem::libcClose(int fd){
+ Util::Thread::ScopedLock scoped(lock);
return manager->close(fd);
}
off_t NetworkSystem::libcLseek(int fd, off_t offset, int whence){
+ Util::Thread::ScopedLock scoped(lock);
return manager->lseek(fd, offset, whence);
}
}
/* NOTE FIXME Missing I/O in Native Client */
Nacl::NetworkSystem & getSystem(){
return (Nacl::NetworkSystem&) Storage::instance();
}
extern "C" {
/* http://sourceware.org/binutils/docs-2.21/ld/Options.html#index-g_t_002d_002dwrap_003d_0040var_007bsymbol_007d-261
* --wrap=symbol
* Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to __wrap_symbol. Any undefined reference to __real_symbol will be resolved to symbol.
*/
int __wrap_open(const char * path, int mode, int params){
return getSystem().libcOpen(path, mode, params);
}
ssize_t __wrap_read(int fd, void * buf, size_t count){
return getSystem().libcRead(fd, buf, count);
}
extern int __real_close(int fd);
int __wrap_close(int fd){
/* we may be given a file descriptor that we do not own, probably
* because some file descriptors are really tied to sockets so
* if we don't own the fd then pass it to the real close function.
*/
int ok = getSystem().libcClose(fd);
if (ok == -1){
return __real_close(fd);
}
return ok;
}
off_t __wrap_lseek(int fd, off_t offset, int whence){
return getSystem().libcLseek(fd, offset, whence);
}
int pipe (int filedes[2]){
return -1;
}
int mkdir (const char *filename, mode_t mode){
return -1;
}
int access(const char *filename, int how){
return -1;
}
char * getcwd (char *buffer, size_t size){
return NULL;
}
int lstat (const char *path, struct stat *buf){
return -1;
}
int rmdir (const char *filename){
return -1;
}
int chdir (const char *filename){
return -1;
}
int setuid (uid_t newuid){
return 0;
}
int seteuid (uid_t uid){
return 0;
}
uid_t geteuid (void){
return NULL;
}
int setgid (gid_t gid){
return 0;
}
gid_t getgid (void){
return NULL;
}
int setegid (gid_t gid){
return 0;
}
gid_t getegid (void){
return NULL;
}
char * getlogin (void){
return NULL;
}
uid_t getuid(void){
return NULL;
}
struct passwd * getpwuid (uid_t uid){
return NULL;
}
struct passwd * getpwnam (const char *name){
return NULL;
}
struct group * getgrnam(const char *name){
return NULL;
}
struct group * getgrgid(gid_t gid){
return NULL;
}
int link (const char *oldname, const char *newname){
return -1;
}
int unlink (const char *filename){
return -1;
}
int kill(pid_t pid, int sig){
return -1;
}
}
#endif
diff --git a/util/nacl/network-system.h b/util/nacl/network-system.h
index aa730c97..5b0cfa99 100644
--- a/util/nacl/network-system.h
+++ b/util/nacl/network-system.h
@@ -1,56 +1,56 @@
#ifndef _paintown_network_system_h
#define _paintown_network_system_h
#ifdef NACL
#include <string>
#include "../file-system.h"
#include "../thread.h"
namespace pp{
class Instance;
class Core;
}
namespace Nacl{
typedef Path::AbsolutePath AbsolutePath;
typedef Path::RelativePath RelativePath;
class Manager;
class NetworkSystem: public Storage::System {
public:
NetworkSystem(pp::Instance * instance, pp::Core * core);
virtual ~NetworkSystem();
virtual AbsolutePath find(const RelativePath & path);
virtual RelativePath cleanse(const AbsolutePath & path);
virtual bool exists(const RelativePath & path);
virtual bool exists(const AbsolutePath & path);
virtual std::vector<AbsolutePath> getFilesRecursive(const AbsolutePath & dataPath, const std::string & find, bool caseInsensitive = false);
virtual std::vector<AbsolutePath> getFiles(const AbsolutePath & dataPath, const std::string & find, bool caseInsensitive = false);
virtual AbsolutePath configFile();
virtual AbsolutePath userDirectory();
virtual std::vector<AbsolutePath> findDirectories(const RelativePath & path);
virtual AbsolutePath findInsensitive(const RelativePath & path);
virtual AbsolutePath lookupInsensitive(const AbsolutePath & directory, const RelativePath & path);
public:
int libcOpen(const char * path, int mode, int params);
ssize_t libcRead(int fd, void * buf, size_t count);
int libcClose(int fd);
off_t libcLseek(int fd, off_t offset, int whence);
protected:
pp::Instance * instance;
pp::Core * core;
- /* used to communicate to the main NACL thread */
- // Util::Thread::LockObject portal;
+ /* only one thread at a time to access the network system */
+ Util::Thread::LockObject lock;
Manager * manager;
};
}
#endif
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jun 11, 10:22 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68378
Default Alt Text
(35 KB)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline