From 18ac48230ab17ee05ed4b717d858a20879f851f9 Mon Sep 17 00:00:00 2001 From: blacksirius Date: Fri, 1 Jun 2012 14:21:02 +0000 Subject: removed the old obsolete Plugin system (commit 1/2) - Removed @ Autoconf/make and CMake, VC Projects will be cleaned in a additional commit. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16203 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/plugins/console.c | 496 -------------------------------------------------- 1 file changed, 496 deletions(-) delete mode 100644 src/plugins/console.c (limited to 'src/plugins/console.c') diff --git a/src/plugins/console.c b/src/plugins/console.c deleted file mode 100644 index fc883a9f3..000000000 --- a/src/plugins/console.c +++ /dev/null @@ -1,496 +0,0 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder - -#include "../common/plugin.h" - -#ifdef WIN32 - #define WIN32_LEAN_AND_MEAN - #include -#else - #define __USE_XOPEN - #include - #include - #include - #include -#endif -#include // stdin, fgets - -#define INPUT_BUFSIZE 4096 -#define INPUT_INVALID 0 -#define INPUT_READY 1 -#define INPUT_WAITING 2 -#define INPUT_READING 3 -#define INPUT_CLOSED 4 - -////////////////////////////// -#ifdef WIN32 -////////////////////////////// - -// In windows the worker is a thread so it can access the same variables. -#define WORKER_FUNC_DECLARE(name) DWORD WINAPI worker_ ## name(LPVOID lpParameter) -#define WORKER_FUNC_START(name) DWORD WINAPI worker_ ## name(LPVOID lpParameter) { (void)lpParameter; { -#define WORKER_FUNC_END(name) } ExitThread(0); return 0; } -#define WORKER_EXECUTE(name,errvar) \ - do{ \ - DWORD dwThreadId; \ - buf.worker = CreateThread(NULL, 0, worker_ ## name, NULL, CREATE_SUSPENDED, &dwThreadId); \ - *(errvar) = ( buf.worker == NULL ); \ - }while(0) - -/// Buffer for asynchronous input -typedef struct _buffer { - char arr[INPUT_BUFSIZE]; - size_t len; - HANDLE worker; - HANDLE state_mux; // mutex for the state - char state; -} BUFFER; - -////////////////////////////// -#else -////////////////////////////// - -/// In linux the worker is a process so it needs to comunicate through pipes. -#define WORKER_FUNC_DECLARE(name) void worker_ ## name(void) -#define WORKER_FUNC_START(name) void worker_ ## name(void) { -#define WORKER_FUNC_END(name) _exit(0); } -#define WORKER_EXECUTE(name,errvar) \ - do{ \ - int pid = fork(); \ - if( pid == 0 ){ \ - worker_ ## name(); \ - } \ - *(errvar) = (pid == -1); \ - }while(0) - -#define PIPE_READ 0 -#define PIPE_WRITE 1 - -/// Buffer for asynchronous input -typedef struct _buffer { - char arr[INPUT_BUFSIZE]; - size_t len; - int data_pipe[2]; // pipe to receive data - int state_pipe[2]; // pipe to send state - char state; - unsigned close_unused_flag : 1; -} BUFFER; - -////////////////////////////// -#endif -////////////////////////////// - - - - - -////// Plugin information //////// - - - - - -PLUGIN_INFO = { - "Console", // Name - PLUGIN_ALL, // Target servers - "0.1", // Version - "1.03", // Minimum plugin engine version to run - "Console parser" // Short description -}; - -////// Plugin event list ////////// -// Format: , -// All registered functions to a event gets executed -// (In descending order) when its called. -// Multiple functions can be called by multiple events too, -// So it's up to your creativity ^^ -// -PLUGIN_EVENTS_TABLE = { - { "console_init", EVENT_PLUGIN_INIT }, - { "console_final", EVENT_PLUGIN_FINAL }, - { "console_autostart", EVENT_ATHENA_INIT }, - //{ "console_start", EVENT_CONSOLE_START },//## add these events to the plugins framework - //{ "console_stop", EVENT_CONSOLE_STOP }, - { "console_stop", EVENT_ATHENA_FINAL }, - { NULL, NULL } -}; - - - - - -///// Variables ///// - - - - - -// Imported functions -typedef int (*TimerFunc)(int tid, unsigned int tick, int id, intptr_t data); -int (*add_timer_func_list)(TimerFunc func, char* name); -int (*add_timer_interval)(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval); -int (*delete_timer)(int tid, TimerFunc func); -unsigned int (*gettick)(void); -int (*parse_console)(const char* buf); - -// Locals -int tid = -1; // timer id -BUFFER buf; // input buffer -WORKER_FUNC_DECLARE(getinput); // worker for the input buffer - - - - - -//////// Asynchronous input functions ////////// - - - - - -////////////////////////////// -#ifdef WIN32 -////////////////////////////// -// -// --=== Asynchronous console input ===-- -// -// On windows a thread is used (both threads have access to the same data). -// The worker threads starts suspended and is resumed when data is required. -// After getting the data, the worker thread updates the state variable and -// suspends itself. -// -// A mutex is used to synchronize access to the state variable between the -// threads. Access and updates to state are probably already atomic so the -// mutex shouldn't be needed, but using it is more correct so it stays. -// -// Note: The Worker thread only starts to get input data when further data is -// requested. This is a design choise and brings no real advantage or -// disadvantage I can think of. -// - -/// Returns the state of the input -char input_getstate() -{ - char state; - - WaitForSingleObject(buf.state_mux, INFINITE); - state = buf.state; - ReleaseMutex(buf.state_mux); - - return state; -} - -/// Sets the state of the input -void input_setstate(char state) -{ - char oldstate; - - // update state - WaitForSingleObject(buf.state_mux, INFINITE); - oldstate = buf.state; - buf.state = state; - ReleaseMutex(buf.state_mux); - - if( state == INPUT_READY && oldstate == INPUT_READING ) - {// data has become available - SuspendThread(buf.worker); - } else if( state == INPUT_WAITING ) - {// input is waiting for data - ResumeThread(buf.worker); - //} else if( state == INPUT_READING ) - //{// worker is reading data - } else if( state == INPUT_CLOSED ) - {// end the input - CloseHandle(buf.state_mux); - TerminateThread(buf.worker, 0); - } -} - -/// Gets the next state of the input -#define input_nextstate() input_getstate() - -/// Returns if data is available from asynchronous input. -/// Requests data if none is available. -int input_hasdata(void) -{ - if( input_getstate() == INPUT_READY ) - {// buffer is ready - if( buf.len > 0 ) - return 1; // data found ;) - // request data from the worker - input_setstate(INPUT_WAITING); - } - return 0; // no data -} - -/// Initialize asynchronous input -int input_init(void) -{ - int err = 0; - - memset(&buf, 0, sizeof(buf)); - buf.state_mux = CreateMutex(NULL, FALSE, NULL); - if( buf.state_mux == NULL ) - {// failed to create state mutex - return 1; - } - buf.len = 0; - input_setstate(INPUT_READY); - WORKER_EXECUTE(getinput, &err); - if( err ) - {// failed to start worker - input_setstate(INPUT_CLOSED); - } - - return err; -} - -/// Finalize asynchronous input -int input_final(void) -{ - input_setstate(INPUT_CLOSED); - return 0; -} - -////////////////////////////// -#else -////////////////////////////// -// -// --=== Asynchronous console input ===-- -// -// On the other systems a process is used and pipes are used to comunicate. -// The worker process receives status updates through one of the pipes either -// requesting data or ending the worker. -// The other pipe is used by the worker to send the input data and is checked -// for data by the main thread in the timer function. -// -// Note: The Worker thread only starts to get input data when further data is -// requested. This is a design choise and brings no real advantage or -// disadvantage I can think of. -// - -/// Returns the state of the input -#define input_getstate() buf.state - -/// Sets the state of the input -void input_setstate(char state) { - size_t fileReadCount = 0; - if( state == INPUT_READY && input_getstate() == INPUT_READING ) {// send data from the worker to the main process - fileReadCount = write(buf.data_pipe[PIPE_WRITE], &buf.len, sizeof(buf.len)); - fileReadCount = write(buf.data_pipe[PIPE_WRITE], &buf.arr, buf.len); - } else if( state == INPUT_WAITING ) { - if( buf.close_unused_flag == 0 ) {// close unused pipe sides in the main process - close(buf.data_pipe[PIPE_WRITE]); - close(buf.state_pipe[PIPE_READ]); - buf.close_unused_flag = 1; - } - // send the next state - fileReadCount = write(buf.state_pipe[PIPE_WRITE], &state, sizeof(state)); - } else if( state == INPUT_READING ) { - if( buf.close_unused_flag == 0 ) {// close unused pipe sides in the worker process - close(buf.data_pipe[PIPE_READ]); - close(buf.state_pipe[PIPE_WRITE]); - buf.close_unused_flag = 1; - } - } else if( state == INPUT_CLOSED ) {// send next state to the worker and close the pipes - fileReadCount = write(buf.state_pipe[PIPE_WRITE], &state, sizeof(state)); - close(buf.data_pipe[PIPE_WRITE]); - close(buf.data_pipe[PIPE_READ]); - close(buf.state_pipe[PIPE_WRITE]); - close(buf.state_pipe[PIPE_READ]); - } - buf.state = state; -} - -/// Waits for the next state of the input -char input_nextstate() -{ - char state = INPUT_CLOSED; - int bytes = 0; - - while( bytes == 0 ) - bytes = read(buf.state_pipe[PIPE_READ], &state, sizeof(state)); - if( bytes == -1 ) - {// error, terminate worker - input_setstate(INPUT_CLOSED); - } - return state; -} - -/// Returns if data is available from asynchronous input. -/// If data is available, it's put in the local buffer. -int input_hasdata() -{ - struct pollfd fds; - int hasData; - size_t fileReadCount; - - - if( input_getstate() == INPUT_READY ) {// start getting data - input_setstate(INPUT_WAITING); - return 0; - } - // check if data is available - fds.fd = buf.data_pipe[PIPE_READ]; - fds.events = POLLRDNORM; - hasData = ( poll(&fds,1,0) > 0 ); - if( hasData ) {// read the data from the pipe - fileReadCount = read(buf.data_pipe[PIPE_READ], &buf.len, sizeof(buf.len)); - fileReadCount = read(buf.data_pipe[PIPE_READ], buf.arr, buf.len); - input_setstate(INPUT_READY); - } - - return hasData; -} - -/// Initialize asynchronous input -int input_init(void) -{ - int err = 0; - - memset(&buf, 0, sizeof(buf)); - if( pipe(buf.data_pipe) ) - {// error creating data pipe - return 1; - } - if( pipe(buf.state_pipe) ) - {// error creating state pipe - close(buf.data_pipe[PIPE_READ]); - close(buf.data_pipe[PIPE_WRITE]); - return 1; - } - buf.len = 0; - input_setstate(INPUT_READY); - WORKER_EXECUTE(getinput, &err); - if( err ){ - //printf("input_init failed to start worker (%d)\n", err); - input_setstate(INPUT_CLOSED); - } - - return err; -} - -/// Finalize asynchronous input -int input_final(void) -{ - close(buf.data_pipe[PIPE_READ]); - close(buf.data_pipe[PIPE_WRITE]); - close(buf.state_pipe[PIPE_READ]); - close(buf.state_pipe[PIPE_WRITE]); - return 0; -} - -////////////////////////////// -#endif -////////////////////////////// - - - -/// Returns the input data array -#define input_getdata() buf.arr - -/// Returns the input data length -#define input_getlen() buf.len - -/// Clear the input data -#define input_clear() ( buf.len = 0 ) - -/// Worker thread/process that gets input -WORKER_FUNC_START(getinput) - while( input_nextstate() != INPUT_CLOSED ) - {// get input - input_setstate(INPUT_READING); - buf.arr[0] = '\0'; - if( fgets(buf.arr, INPUT_BUFSIZE, stdin) != NULL ) - buf.len = strlen(buf.arr); - input_setstate(INPUT_READY); - } -WORKER_FUNC_END(getinput) - - - - - -//////// Plugin console functions ////////// - - - - - -/// Timer function that checks if there's assynchronous input data and feeds parse_console() -/// The input reads one line at a time and line terminators are removed. -int console_getinputtimer(int tid, unsigned int tick, int id, intptr_t data) -{ - char* cmd; - size_t len; - - if( input_hasdata() ){ - - // get data (removes line terminators) - cmd = input_getdata(); - len = input_getlen(); - while( len > 0 && (cmd[len-1] == '\r' || cmd[len-1] == '\n') ) - cmd[--len] = '\0'; - - // parse data - parse_console(cmd); - input_clear(); - } - - return 0; -} - -/// Start the console -void console_start(void) -{ - if( input_init() ){ - return; - } - //##TODO add a 'startupcmd' config options - //parse_console("help"); - add_timer_func_list(console_getinputtimer,"console_getinputtimer"); - tid = add_timer_interval(gettick(),console_getinputtimer,0,0,250);//##TODO add a 'timerperiod' config option -} - -void console_autostart(void) -{//##TODO add an 'autostart' config option - console_start(); -} - -/// Stop the console -void console_stop(void) -{ - if( tid != -1 ){ - delete_timer(tid, console_getinputtimer); - input_final(); - } - return; -} - -/// Test the console for compatibility -int console_test(void) -{// always compatible at the moment, maybe test if standard input is available? - return 1; -} - - -/// Initialize the console -void console_init(void) -{ - // import symbols - IMPORT_SYMBOL(add_timer_interval, SYMBOL_ADD_TIMER_INTERVAL); - IMPORT_SYMBOL(add_timer_func_list, SYMBOL_ADD_TIMER_FUNC_LIST); - IMPORT_SYMBOL(delete_timer, SYMBOL_DELETE_TIMER); - IMPORT_SYMBOL(gettick, SYMBOL_GETTICK); - IMPORT_SYMBOL(parse_console, SYMBOL_PARSE_CONSOLE); - //printf("%d -> add_timer_func_list=0x%x\n", SYMBOL_ADD_TIMER_FUNC_LIST, (int)add_timer_func_list); - //printf("%d -> add_timer_interval=0x%x\n", SYMBOL_ADD_TIMER_INTERVAL, (int)add_timer_interval); - //printf("%d -> delete_timer=0x%x\n", SYMBOL_DELETE_TIMER, (int)delete_timer); - //printf("%d -> gettick=0x%x\n", SYMBOL_GETTICK, (int)gettick); - //printf("%d -> parse_console=0x%x\n", SYMBOL_PARSE_CONSOLE, (int)parse_console); -} - -/// Finalize the console -void console_final(void) -{ -} -- cgit v1.2.3-60-g2f50