Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
35 KB
Referenced Files
None
Subscribers
None
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

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)

Event Timeline