void WorkerBinding::CreateWorker(const ValueList& args, SharedValue result)
	{
		if (args.size()!=2)
		{
			throw ValueException::FromString("invalid argument specified");
		}
		
		bool is_function = args.at(1)->ToBool();
		
		std::string code;
		Logger *logger = Logger::Get("Worker");
		
		if (is_function)
		{
			// convert the function to a string block 
			code =  "(";
			code += args.at(0)->ToString();
			code += ")()";
		}
		else 
		{
			// this is a path -- probably should verify that this is relative and not an absolute URL to remote
			SharedKMethod appURLToPath = global->GetNS("App.appURLToPath")->ToMethod();
			ValueList a;
			a.push_back(args.at(0));
			SharedValue result = appURLToPath->Call(a);
			const char *path = result->ToString();
			
			logger->Debug("worker file path = %s",path);
			
			std::ios::openmode flags = std::ios::in;
			Poco::FileInputStream *fis = new Poco::FileInputStream(path,flags);
			std::stringstream ostr;
			char buf[8096];
			int count = 0;
			while(!fis->eof())
			{
				fis->read((char*)&buf,8095);
				std::streamsize len = fis->gcount();
				if (len>0)
				{
					buf[len]='\0';
					count+=len;
					ostr << buf;
				}
				else break;
			}
			fis->close();
			code = std::string(ostr.str());
		}
		
		logger->Debug("Worker script code = %s", code.c_str());
		
		SharedKObject worker = new Worker(host,global,code);
		result->SetObject(worker);
	}
Example #2
0
int main(int argc, char ** argv) {
	try {
		Appender errApp("Error.log", Level::ERROR, false);
		Appender debugApp("Debug.log", Level::DEBUG, true);
		Appender * dynApp = new Appender("Dynamic.log", Level::INFO, false);
		try {
			Appender badApp("Error.log", Level::ERROR, false);
		} catch ( exception & e ) {
			cout << "Correctly failed to open two appenders to one file." << endl;
		}
		logger1.Error("This should show up for all Appenders");
		delete dynApp;
		logger1.Error("This should only be in Error and Debug");
		logger2.Info("This should only be in debug");
		Appender::enableConsole(Level::INFO);
		logger1.Info("This should show up on the console.");
		logger2.Debug("This should only be in the debug log");
		fLogger.Info("Entering Foo");
		foo();
		fLogger.Info("Exiting foo.");
		Appender::enableConsole(Level::DEBUG);
		logger2.Debug("This will be in the console.");
		logger1.fDebug("%s - %i", "format test", 42);
		Appender::disableConsole();
		logger2.Debug("This will not be on the console.");
		logger1.Error("Exiting");
	} catch ( exception & e ) {
		cerr << "Unhandled exception: ";
		cerr << e.what() << endl;
		cerr << "Exiting." << endl;
		return 1;
	}
	return 0;
}
	void WorkerContext::Sleep(const ValueList &args, KValueRef result)
	{
		Logger *logger = Logger::Get("WorkerContext");
		long ms = args.at(0)->ToInt();
		logger->Debug("worker is sleeping for %d ms", ms);
		condmutex.lock();
		if (condition.tryWait(condmutex, ms))
		{
			logger->Debug("worker sleep was interrupted");
			condmutex.unlock();
			throw ValueException::FromString("interrupted");
			return;
		}
		condmutex.unlock();
		logger->Debug("worker sleep completed");
	}
	void WorkerContext::SendQueuedMessages()
	{
		Logger *logger = Logger::Get("WorkerContext");
		logger->Debug("SendQueuedMessages called");
		
		SharedValue onmessage = worker->Get("onmessage");
		Poco::ScopedLock<Poco::Mutex> lock(mutex);
		if (onmessage->IsMethod())
		{
			if (messages.size()>0)
			{
				std::list<SharedValue>::iterator i = messages.begin();
				while(i!=messages.end())
				{
					SharedValue v = (*i++);
					ValueList _args;
					string name = "worker.message";
					AutoPtr<KEventObject> target = this;
					this->duplicate();
					AutoPtr<Event> event = new Event(target, name);
					event->Set("message", v);
					_args.push_back(Value::NewObject(event));
					host->InvokeMethodOnMainThread(onmessage->ToMethod(),_args,false);
				}
				messages.clear();
			}
		}
	}
Example #5
0
void test_Logger(){
    {
        Logger lg;
        lg.Log(LOG_WARN, "Test logger");
        lg.Debug("logger debug");
        lg.Fatal("Fatal test [%s] [%d]", "args", 1);
        lg.SetHandler("test_log");
        lg.SetLevel(LOG_ALL);
        lg.Info("info test [%s]", "args");
        Logger* lg_ptr = Logger::GetLogger("test");
        lg_ptr->Error("You can see me in file test");
        Logger* lg_ptr2 = Logger::GetLogger();
        lg_ptr2->Error("You can see me in console");
    }
    {
        LOG(LOG_DEBUG, "log debug info: %s", "Hello"); 
    }    
    {
        SetLogger(LOG_WARN, "test_logger.log");
        LOG(LOG_DEBUG, "DEBUG NO SEE, you should not see this");
        LOG(LOG_ERROR, "ERROR, you should know");
        LOG(LOG_WARN, "WARN, you should see this");
    }    
    {
        SetLogger(LOG_ALL);
        LOG(LOG_DEBUG, "DEBUG [%d], you should see this", LOG_DEBUG);
        LOG(LOG_WARN,  "LOG_WARN [%d], you should see this", LOG_WARN);
        LOG(LOG_ERROR, "LOG_ERROR [%d], you should see this", LOG_ERROR);
        LOG(LOG_FATAL, "LOG_FATAL [%d], you should see this", LOG_FATAL);
    }
}
Example #6
0
	void AsyncCopy::Copy(Poco::Path &src, Poco::Path &dest)
	{
		Logger* logger = Logger::Get("Filesystem.AsyncCopy");
		std::string srcString = src.toString();
		std::string destString = dest.toString();
		Poco::File from(srcString);
		bool isLink = from.isLink();

		logger->Debug("file=%s dest=%s link=%i", srcString.c_str(), destString.c_str(), isLink);
#ifndef OS_WIN32
		if (isLink)
		{
			char linkPath[PATH_MAX];
			ssize_t length = readlink(from.path().c_str(), linkPath, PATH_MAX);
			linkPath[length] = '\0';

			std::string newPath (dest.toString());
			const char *destPath = newPath.c_str();
			unlink(destPath); // unlink it first, fails in some OS if already there
			int result = symlink(linkPath, destPath);

			if (result == -1)
			{
				std::string err = "Copy failed: Could not make symlink (";
				err.append(destPath);
				err.append(") from ");
				err.append(linkPath);
				err.append(" : ");
				err.append(strerror(errno));
				throw kroll::ValueException::FromString(err);
			}
		}
#endif
		if (!isLink && from.isDirectory())
		{
			Poco::File d(dest.toString());
			if (!d.exists())
			{
				d.createDirectories();
			}
			std::vector<std::string> files;
			from.list(files);
			std::vector<std::string>::iterator i = files.begin();
			while(i!=files.end())
			{
				std::string fn = (*i++);
				Poco::Path sp(kroll::FileUtils::Join(src.toString().c_str(),fn.c_str(),NULL));
				Poco::Path dp(kroll::FileUtils::Join(dest.toString().c_str(),fn.c_str(),NULL));
				this->Copy(sp,dp);
			}
		}
		else if (!isLink)
		{
			// in this case it's a regular file
			Poco::File s(src.toString());
			s.copyTo(dest.toString().c_str());
		}
	}
Example #7
0
	void Worker::Terminate(const ValueList& args, SharedValue result)
	{
		Logger *logger = Logger::Get("Worker");
		logger->Debug("Terminate called");
		
		Poco::ScopedLock<Poco::Mutex> lock(mutex);
		if (!stopped)
		{
			stopped=true;
			this->condition.signal();
		}
	}
	void WorkerContext::PostMessage(const ValueList &args, KValueRef result)
	{
		Logger *logger = Logger::Get("WorkerContext");
		KValueRef message(args.at(0));

		logger->Debug("PostMessage called with %s", message->DisplayString()->c_str());
		{
			Poco::ScopedLock<Poco::Mutex> lock(mutex);
			messages.push_back(message);
		}
		SendQueuedMessages();
	}
Example #9
0
	bool FileStream::Open(FileStreamMode mode, bool binary, bool append)
	{
		// close the prev stream if needed
		this->Close();

		try
		{
			std::ios::openmode flags = (std::ios::openmode) 0;
			bool output = false;
			if (binary)
			{
				flags|=std::ios::binary;
			}
			if (mode == MODE_APPEND)
			{
				flags|=std::ios::out|std::ios::app;
				output = true;
			}
			else if (mode == MODE_WRITE)
			{
				flags |= std::ios::out|std::ios::trunc;
				output = true;
			}
			else if (mode == MODE_READ)
			{
				flags |= std::ios::in;
			}

#ifdef DEBUG
			Logger* logger = Logger::Get("Filesystem.FileStream");
			logger->Debug("FILE OPEN FLAGS = %d, binary=%d, mode=%d, append=%d",flags,binary,(int)mode,append);
#endif
			if (output)
			{
				this->stream = new Poco::FileOutputStream(this->filename,flags);
#ifndef OS_WIN32
				chmod(this->filename.c_str(),S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
#endif		
			}
			else
			{
				this->stream = new Poco::FileInputStream(this->filename,flags);
			}
			return true;
		}
		catch (Poco::Exception& exc)
		{
			Logger* logger = Logger::Get("Filesystem.FileStream");
			logger->Error("Error in open. Exception: %s",exc.displayText().c_str());
			throw ValueException::FromString(exc.displayText());
		}
	}
Example #10
0
	void Worker::Start(const ValueList& args, SharedValue result)
	{
		Logger *logger = Logger::Get("Worker");
		logger->Debug("Start called");
		if (!stopped)
		{
			throw ValueException::FromString("Worker already started");
			return;
		}
		this->context = new WorkerContext(host,this);
		this->adapter = new Poco::RunnableAdapter<Worker>(*this, &Worker::Run);
		this->thread.start(*adapter);
	}
	void WorkerContext::ImportScripts(const ValueList &args, KValueRef result)
	{
		Logger *logger = Logger::Get("WorkerContext");
		AutoPtr<Worker> _worker = worker.cast<Worker>();
		JSGlobalContextRef context = KJSUtil::GetGlobalContext(_worker->GetGlobalObject());

		for (size_t c = 0; c < args.size(); c++)
		{
			std::string path(URLUtils::URLToPath(args.GetString(c)));
			logger->Debug("Attempting to import worker script = %s", path.c_str());
			KJSUtil::EvaluateFile(context, path.c_str());
		}
	}
	void WorkerContext::PostMessage(const ValueList &args, SharedValue result)
	{
		Logger *logger = Logger::Get("WorkerContext");
		logger->Debug("PostMessage called");
		try
		{
			Poco::ScopedLock<Poco::Mutex> lock(mutex);
			messages.push_back(args.at(0));
			SendQueuedMessages();
		}
		catch(std::exception &e)
		{
			logger->Error("Error calling onmessage for worker. Error = %s",e.what());
		}
	}
	void WorkerContext::ImportScripts(const ValueList &args, SharedValue result)
	{
		Logger *logger = Logger::Get("WorkerContext");
		
		SharedKMethod appURLToPath = host->GetGlobalObject()->GetNS("App.appURLToPath")->ToMethod();
		AutoPtr<Worker> _worker = worker.cast<Worker>();
		JSGlobalContextRef context = KJSUtil::GetGlobalContext(_worker->GetGlobalObject());
		
		for (size_t c = 0; c < args.size(); c++)
		{
			// first convert the path to a full URL file path
			ValueList a;
			a.push_back(args.at(c));
			SharedValue result = appURLToPath->Call(a);
			const char *path = result->ToString();

			logger->Debug("attempting to import worker script = %s",path);
			KJSUtil::EvaluateFile(context, (char*)path);
		}
	}
	void WorkerContext::SendQueuedMessages()
	{
		Logger *logger = Logger::Get("WorkerContext");
		logger->Debug("SendQueuedMessages called");

		if (messages.size() <= 0)
			return;

		KValueRef onMessageValue = worker->Get("onmessage");
		if (!onMessageValue->IsMethod())
			return;

		KMethodRef onMessage(onMessageValue->ToMethod());
		Poco::ScopedLock<Poco::Mutex> lock(mutex);
		std::list<KValueRef>::iterator i = messages.begin();
		while (i != messages.end())
		{
			KValueRef message(*i++);
			this->CallOnMessageCallback(onMessage, message);
		}
		messages.clear();
	}
Example #15
0
	void AsyncCopy::Run(void* data)
	{
		START_KROLL_THREAD;

		Logger* logger = Logger::Get("Filesystem.AsyncCopy");

		AsyncCopy* ac = static_cast<AsyncCopy*>(data);
		std::vector<std::string>::iterator iter = ac->files.begin();
		Poco::Path to(ac->destination);
		Poco::File tof(to.toString());

		logger->Debug("Job started: dest=%s, count=%i", ac->destination.c_str(), ac->files.size());
		if (!tof.exists())
		{
			tof.createDirectory();
		}
		int c = 0;
		while (!ac->stopped && iter!=ac->files.end())
		{
			bool err_copy = false;
			std::string file = (*iter++);
			c++;

			logger->Debug("File: path=%s, count=%i\n", file.c_str(), c);
			try
			{
				Poco::Path from(file);
				Poco::File f(file);
				if (f.isDirectory())
				{
					ac->Copy(from,to);
				}
				else
				{
					Poco::Path dest(to,from.getFileName());
					ac->Copy(from,dest);
				}
				logger->Debug("File copied");

				KValueRef value = Value::NewString(file);
				ValueList args;
				args.push_back(value);
				args.push_back(Value::NewInt(c));
				args.push_back(Value::NewInt(ac->files.size()));
				args.push_back(Value::NewBool(true));
				RunOnMainThread(ac->callback, args, false);

				logger->Debug("Callback executed");
			}
			catch (ValueException &ex)
			{
				err_copy = true;
				SharedString ss = ex.DisplayString();
				logger->Error(std::string("Error: ") + *ss + " for file: " + file);
			}
			catch (Poco::Exception &ex)
			{
				err_copy = true;
				logger->Error(std::string("Error: ") + ex.displayText() + " for file: " + file);
			}
			catch (std::exception &ex)
			{
				err_copy = true;
				logger->Error(std::string("Error: ") + ex.what() + " for file: " + file);
			}
			catch (...)
			{
				err_copy = true;
				logger->Error(std::string("Unknown error during copy: ") + file);
			}
			try
			{
				if(err_copy)
				{
					KValueRef value = Value::NewString(file);
					ValueList args;
					args.push_back(value);
					args.push_back(Value::NewInt(c));
					args.push_back(Value::NewInt(ac->files.size()));
					args.push_back(Value::NewBool(false));
					RunOnMainThread(ac->callback, args, false);
				}
			}
			catch(...)
			{
				err_copy = true;
				logger->Error(std::string("Unknown error during copy: ") + file);
			}

		}
		ac->Set("running",Value::NewBool(false));
		ac->stopped = true;

		logger->Debug(std::string("Job finished"));

		END_KROLL_THREAD;
	}
Example #16
0
	void Worker::Run()
	{
		Logger *logger = Logger::Get("Worker");
		
		bool error = false;
		JSGlobalContextRef context = NULL;
		
		try
		{
			// create a new global context
			this->global_object = KJSUtil::CreateNewGlobalContext(this->host);
			
			// bind the worker context properties
			KJSUtil::BindProperties(global_object,this->context);
			
			// evaluate the script
			context = KJSUtil::GetGlobalContext(global_object);
			KJSUtil::Evaluate(context, (char*)this->code.c_str());
		}
		catch(std::exception &e)
		{
			error = true;
			logger->Error("Error loading worker. Error = %s", e.what());
			SharedValue onerror = this->Get("onerror");
			if (onerror->IsMethod())
			{
				SharedKMethod method = onerror->ToMethod();
				ValueList args;
				args.push_back(Value::NewString(e.what()));
				this->host->InvokeMethodOnMainThread(method,args,false);
			}
		}
		
		if (!error)
		{
			// run this thread and wait for pending messages or to be 
			// woken up to stop
			for(;;)
			{
				bool wait = true;
				{
					Poco::ScopedLock<Poco::Mutex> lock(mutex);
					if (this->messages.size()>0)
					{
						wait=false;
					}
				}
				if (wait)
				{
					condmutex.lock(); // will unlock in wait
					condition.wait(condmutex);
				}
				// check to see if the worker wants to receive messages - we do this 
				// each time since they could define at any time
				SharedValue mv = KJSUtil::GetProperty(global_object,"onmessage");
				if (mv->IsMethod())
				{
					// we have to make a copy since calling the onmessage could be re-entrant
					// which would cause the postMessage to deadlock. we hold the lock to 
					// make a copy of the contents of the list and then iterate w/o lock
					std::list<SharedValue> copy;
					{
						// lock inside block only to make copy
						Poco::ScopedLock<Poco::Mutex> lock(mutex);
						if (this->messages.size()>0)
						{
							std::list<SharedValue>::iterator i = this->messages.begin();
							while (i!=this->messages.end())
							{
								SharedValue message = (*i++);
								copy.push_back(message);
							}
							this->messages.clear();
						}
					}
					if (copy.size()>0)
					{
						SharedKMethod onmessage = mv->ToMethod();
						std::list<SharedValue>::iterator i = copy.begin();
						while(i!=copy.end())
						{
							SharedValue message = (*i++);
						
							try
							{
								ValueList args;
								string name = "worker.message";
								AutoPtr<KEventObject> target = this;
								this->duplicate();
								AutoPtr<Event> event = new Event(target, name);
								event->Set("message", message);
								args.push_back(Value::NewObject(event));
								host->InvokeMethodOnMainThread(onmessage,args,false);
							}
							catch(std::exception &e)
							{
								logger->Error("Error dispatching worker message, exception = %s",e.what());
							}
						}
					}
				}
				if (stopped) break;
			}
		}
		
		// make sure we unregister our global so we don't leak
		if (global_object!=NULL)
		{
			KJSUtil::UnregisterGlobalContext(global_object);
		}
		
		this->global_object = NULL;
		this->stopped = true;
		
		logger->Debug("exiting Worker thread");
	}