Trimmed trailing whitespaces in /src/common

This commit is contained in:
Lemongrass3110 2016-09-05 19:35:51 +02:00
parent 366aeeaafe
commit cc9d08538a
30 changed files with 766 additions and 766 deletions

View File

@ -4,16 +4,16 @@
#ifndef _rA_ATOMIC_H_ #ifndef _rA_ATOMIC_H_
#define _rA_ATOMIC_H_ #define _rA_ATOMIC_H_
// Atomic Operations // Atomic Operations
// (Interlocked CompareExchange, Add .. and so on ..) // (Interlocked CompareExchange, Add .. and so on ..)
// //
// Implementation varies / depends on: // Implementation varies / depends on:
// - Architecture // - Architecture
// - Compiler // - Compiler
// - Operating System // - Operating System
// //
// our Abstraction is fully API-Compatible to Microsofts implementation @ NT5.0+ // our Abstraction is fully API-Compatible to Microsofts implementation @ NT5.0+
// //
#include "cbasetypes.h" #include "cbasetypes.h"
#if defined(_MSC_VER) #if defined(_MSC_VER)
@ -29,14 +29,14 @@ forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch,
_asm{ _asm{
lea esi,_cmp; lea esi,_cmp;
lea edi,exch; lea edi,exch;
mov eax,[esi]; mov eax,[esi];
mov edx,4[esi]; mov edx,4[esi];
mov ebx,[edi]; mov ebx,[edi];
mov ecx,4[edi]; mov ecx,4[edi];
mov esi,dest; mov esi,dest;
lock CMPXCHG8B [esi]; lock CMPXCHG8B [esi];
} }
} }
@ -88,11 +88,11 @@ forceinline volatile int64 InterlockedExchange64(volatile int64 *target, int64 v
#elif defined(__GNUC__) #elif defined(__GNUC__)
// The __sync functions are available on x86 or ARMv6+ // The __sync functions are available on x86 or ARMv6+
//need to proper dig into arm macro, //need to proper dig into arm macro,
//see http://sourceforge.net/p/predef/wiki/Architectures/ //see http://sourceforge.net/p/predef/wiki/Architectures/
#if !defined(__x86_64__) && !defined(__i386__) \ #if !defined(__x86_64__) && !defined(__i386__) \
&& ( !defined(__ARM_ARCH_VERSION__) || __ARM_ARCH_VERSION__ < 6 ) \ && ( !defined(__ARM_ARCH_VERSION__) || __ARM_ARCH_VERSION__ < 6 ) \
&& ( !defined(__ARM_ARCH) && __ARM_ARCH < 6 ) && ( !defined(__ARM_ARCH) && __ARM_ARCH < 6 )
#error Your Target Platfrom is not supported #error Your Target Platfrom is not supported
#endif #endif

View File

@ -62,7 +62,7 @@ void config_setting_copy_elem(config_setting_t *parent, const config_setting_t *
config_setting_set_format(set, src->format); config_setting_set_format(set, src->format);
} else if (CONFIG_TYPE_INT64 == config_setting_type(src)) { } else if (CONFIG_TYPE_INT64 == config_setting_type(src)) {
set = config_setting_set_int64_elem(parent, -1, config_setting_get_int64(src)); set = config_setting_set_int64_elem(parent, -1, config_setting_get_int64(src));
config_setting_set_format(set, src->format); config_setting_set_format(set, src->format);
} else if (CONFIG_TYPE_FLOAT == config_setting_type(src)) { } else if (CONFIG_TYPE_FLOAT == config_setting_type(src)) {
config_setting_set_float_elem(parent, -1, config_setting_get_float(src)); config_setting_set_float_elem(parent, -1, config_setting_get_float(src));
} else if (CONFIG_TYPE_STRING == config_setting_type(src)) { } else if (CONFIG_TYPE_STRING == config_setting_type(src)) {
@ -83,10 +83,10 @@ void config_setting_copy_aggregate(config_setting_t *parent, const config_settin
return; return;
n = config_setting_length(src); n = config_setting_length(src);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (config_setting_is_group(src)) { if (config_setting_is_group(src)) {
config_setting_copy_simple(newAgg, config_setting_get_elem(src, i)); config_setting_copy_simple(newAgg, config_setting_get_elem(src, i));
} else { } else {
config_setting_copy_elem(newAgg, config_setting_get_elem(src, i)); config_setting_copy_elem(newAgg, config_setting_get_elem(src, i));
} }

View File

@ -363,7 +363,7 @@ int main (int argc, char **argv)
do_init(argc,argv); do_init(argc,argv);
// Main runtime cycle // Main runtime cycle
while (runflag != CORE_ST_STOP) { while (runflag != CORE_ST_STOP) {
int next = do_timer(gettick_nocache()); int next = do_timer(gettick_nocache());
do_sockets(next); do_sockets(next);
} }

View File

@ -1339,7 +1339,7 @@ void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...);
/// Resets the length and clears content, so the vector is empty /// Resets the length and clears content, so the vector is empty
/// ///
/// @param __vec Vector /// @param __vec Vector
#define VECTOR_RESET(__vec) \ #define VECTOR_RESET(__vec) \
if( VECTOR_LENGTH(__vec) > 0 ) { \ if( VECTOR_LENGTH(__vec) > 0 ) { \

View File

@ -16,7 +16,7 @@ struct EVDP_DATA{
enum EVDP_EVENTFLAGS{ enum EVDP_EVENTFLAGS{
EVDP_EVENT_IN = 1, // Incomming data EVDP_EVENT_IN = 1, // Incomming data
EVDP_EVENT_OUT = 2, // Connection accepts writing. EVDP_EVENT_OUT = 2, // Connection accepts writing.
EVDP_EVENT_HUP = 4 // Connection Closed. EVDP_EVENT_HUP = 4 // Connection Closed.
}; };
@ -28,7 +28,7 @@ typedef struct EVDP_EVENT{
/** /**
* Network Event Dispatcher Initialization / Finalization routines * Network Event Dispatcher Initialization / Finalization routines
*/ */
void evdp_init(); void evdp_init();
@ -40,22 +40,22 @@ void evdp_final();
* *
* @param *out_ev pointer to array in size at least of max_events. * @param *out_ev pointer to array in size at least of max_events.
* @param max_events max no of events to report with this call (coalesc) * @param max_events max no of events to report with this call (coalesc)
* @param timeout_ticks max time to wait in ticks (milliseconds) * @param timeout_ticks max time to wait in ticks (milliseconds)
* *
* @Note: * @Note:
* The function will block until an event has occured on one of the monitored connections * The function will block until an event has occured on one of the monitored connections
* or the timeout of timeout_ticks has passed by. * or the timeout of timeout_ticks has passed by.
* Upon successfull call (changed connections) this function will write the connection * Upon successfull call (changed connections) this function will write the connection
* Identifier & event to the out_fds array. * Identifier & event to the out_fds array.
* *
* @return 0 -> Timeout, > 0 no of changed connections. * @return 0 -> Timeout, > 0 no of changed connections.
*/ */
int32 evdp_wait(EVDP_EVENT *out_fds, int32 max_events, int32 timeout_ticks); int32 evdp_wait(EVDP_EVENT *out_fds, int32 max_events, int32 timeout_ticks);
/** /**
* Applys the given mask on the given connection. * Applys the given mask on the given connection.
* *
* @param fd connection identifier * @param fd connection identifier
* @param *ep event data pointer for the connection * @param *ep event data pointer for the connection
* @param mask new event mask we're monitoring for. * @param mask new event mask we're monitoring for.
@ -63,20 +63,20 @@ int32 evdp_wait(EVDP_EVENT *out_fds, int32 max_events, int32 timeout_ticks);
//void evdp_apply(int32 fd, EVDP_DATA *ep, int32 mask); //void evdp_apply(int32 fd, EVDP_DATA *ep, int32 mask);
/** /**
* Adds a connection (listner) to the event notification system. * Adds a connection (listner) to the event notification system.
* *
* @param fd connection identifier * @param fd connection identifier
* @param *ep event data pointer for the connection * @param *ep event data pointer for the connection
* *
* @note: * @note:
* Listener type sockets are edge triggered, (see epoll manual for more information) * Listener type sockets are edge triggered, (see epoll manual for more information)
* - This basicaly means that youll receive one event, adn you have to accept until accept returns an error (nothing to accept) * - This basicaly means that youll receive one event, adn you have to accept until accept returns an error (nothing to accept)
* *
* MONITORS by default: IN * MONITORS by default: IN
* *
* @return success indicator. * @return success indicator.
*/ */
bool evdp_addlistener(int32 fd, EVDP_DATA *ep); bool evdp_addlistener(int32 fd, EVDP_DATA *ep);
/** /**
@ -84,9 +84,9 @@ bool evdp_addlistener(int32 fd, EVDP_DATA *ep);
* *
* @param fd connection identifier * @param fd connection identifier
* @param *ep event data pointr for the connection * @param *ep event data pointr for the connection
* *
* @note: * @note:
* *
* MONITORS by default: IN, HUP * MONITORS by default: IN, HUP
* *
* @return success indicator. * @return success indicator.
@ -102,11 +102,11 @@ bool evdp_addclient(int32 fd, EVDP_DATA *ep);
* @note: * @note:
* Outgoing connection type sockets are getting monitored for connection established * Outgoing connection type sockets are getting monitored for connection established
* successfull * successfull
* - if the connection has been established - we're generitng a writable notification .. (send) * - if the connection has been established - we're generitng a writable notification .. (send)
* this is typical for BSD / posix conform network stacks. * this is typical for BSD / posix conform network stacks.
* - Additinionally its edge triggered. * - Additinionally its edge triggered.
* *
* @see evdp_outgoingconnection_established * @see evdp_outgoingconnection_established
* *
* *
* @return success indicator * @return success indicator
@ -114,14 +114,14 @@ bool evdp_addclient(int32 fd, EVDP_DATA *ep);
bool evdp_addconnecting(int32 fd, EVDP_DATA *ep); bool evdp_addconnecting(int32 fd, EVDP_DATA *ep);
/** /**
* Adds an outgoing connection to the normal event notification system after it has been successfully established. * Adds an outgoing connection to the normal event notification system after it has been successfully established.
* *
* @param fd connection identifier * @param fd connection identifier
* @param *ep event data pointer for the conneciton. * @param *ep event data pointer for the conneciton.
* @note * @note
* after this call, its handled like a normal "client" connection (incomming) * after this call, its handled like a normal "client" connection (incomming)
* *
* @rturn success indicator * @rturn success indicator
*/ */
bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep); bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep);
@ -134,19 +134,19 @@ bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep);
* *
* @note: * @note:
* the connection must be already added (as client or listener) * the connection must be already added (as client or listener)
* *
* *
* @return success indicator * @return success indicator
*/ */
bool evdp_writable_add(int32 fd, EVDP_DATA *ep); bool evdp_writable_add(int32 fd, EVDP_DATA *ep);
/** /**
* Removes the connection from writable notification monitoring * Removes the connection from writable notification monitoring
* *
* @param fd connection identifier * @param fd connection identifier
* @param *ep event data pointr for the connection * @param *ep event data pointr for the connection
* *
*/ */
void evdp_writable_remove(int32 fd, EVDP_DATA *ep); void evdp_writable_remove(int32 fd, EVDP_DATA *ep);
/** /**
@ -157,7 +157,7 @@ void evdp_writable_remove(int32 fd, EVDP_DATA *ep);
* *
* *
* @note: * @note:
* this will also clear the given EVENT_DATA block * this will also clear the given EVENT_DATA block
* so the connection slot is in an "initial" blank status / ready to get reused. * so the connection slot is in an "initial" blank status / ready to get reused.
* *
*/ */

View File

@ -1,5 +1,5 @@
// //
// Event Dispatcher Abstraction for EPOLL // Event Dispatcher Abstraction for EPOLL
// //
// Author: Florian Wilkemeyer <fw@f-ws.de> // Author: Florian Wilkemeyer <fw@f-ws.de>
// //
@ -9,30 +9,30 @@
// //
#define EPOLL_MAX_PER_CYCLE 10 // Max Events to coalesc. per cycle. #define EPOLL_MAX_PER_CYCLE 10 // Max Events to coalesc. per cycle.
static int epoll_fd = -1; static int epoll_fd = -1;
void evdp_init(){ void evdp_init(){
epoll_fd = epoll_create( EPOLL_MAX_PER_CYCLE ); epoll_fd = epoll_create( EPOLL_MAX_PER_CYCLE );
if(epoll_fd == -1){ if(epoll_fd == -1){
ShowFatalError("evdp [EPOLL]: Cannot create event dispatcher (errno: %u / %s)\n", errno, strerror(errno) ); ShowFatalError("evdp [EPOLL]: Cannot create event dispatcher (errno: %u / %s)\n", errno, strerror(errno) );
exit(1); exit(1);
} }
}//end: evdp_init() }//end: evdp_init()
void evdp_final(){ void evdp_final(){
if(epoll_fd != -1){ if(epoll_fd != -1){
close(epoll_fd); close(epoll_fd);
epoll_fd = -1; epoll_fd = -1;
} }
}//end: evdp_final() }//end: evdp_final()
@ -40,64 +40,64 @@ int32 evdp_wait(EVDP_EVENT *out_fds, int32 max_events, int32 timeout_ticks){
struct epoll_event l_events[EPOLL_MAX_PER_CYCLE]; struct epoll_event l_events[EPOLL_MAX_PER_CYCLE];
register struct epoll_event *ev; register struct epoll_event *ev;
register int nfds, n; register int nfds, n;
if(max_events > EPOLL_MAX_PER_CYCLE) if(max_events > EPOLL_MAX_PER_CYCLE)
max_events = EPOLL_MAX_PER_CYCLE; max_events = EPOLL_MAX_PER_CYCLE;
nfds = epoll_wait( epoll_fd, l_events, max_events, timeout_ticks); nfds = epoll_wait( epoll_fd, l_events, max_events, timeout_ticks);
if(nfds == -1){ if(nfds == -1){
// @TODO: check if core is in shutdown mode. if - ignroe error. // @TODO: check if core is in shutdown mode. if - ignroe error.
ShowFatalError("evdp [EPOLL]: epoll_wait returned bad / unexpected status (errno: %u / %s)\n", errno, strerror(errno)); ShowFatalError("evdp [EPOLL]: epoll_wait returned bad / unexpected status (errno: %u / %s)\n", errno, strerror(errno));
exit(1); //.. exit(1); //..
} }
// Loop thru all events and copy it to the local ra evdp_event.. struct. // Loop thru all events and copy it to the local ra evdp_event.. struct.
for(n = 0; n < nfds; n++){ for(n = 0; n < nfds; n++){
ev = &l_events[n]; ev = &l_events[n];
out_fds->fd = ev->data.fd; out_fds->fd = ev->data.fd;
out_fds->events = 0; // clear out_fds->events = 0; // clear
if(ev->events & EPOLLHUP) if(ev->events & EPOLLHUP)
out_fds->events |= EVDP_EVENT_HUP; out_fds->events |= EVDP_EVENT_HUP;
if(ev->events & EPOLLIN) if(ev->events & EPOLLIN)
out_fds->events |= EVDP_EVENT_IN; out_fds->events |= EVDP_EVENT_IN;
if(ev->events & EPOLLOUT) if(ev->events & EPOLLOUT)
out_fds->events |= EVDP_EVENT_OUT; out_fds->events |= EVDP_EVENT_OUT;
out_fds++; out_fds++;
} }
return nfds; // 0 on timeout or > 0 .. return nfds; // 0 on timeout or > 0 ..
}//end: evdp_wait() }//end: evdp_wait()
void evdp_remove(int32 fd, EVDP_DATA *ep){ void evdp_remove(int32 fd, EVDP_DATA *ep){
if(ep->ev_added == true){
if( epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &ep->ev_data) != 0){
ShowError("evdp [EPOLL]: evdp_remove - epoll_ctl (EPOLL_CTL_DEL) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
}
ep->ev_data.events = 0; // clear struct.
ep->ev_data.data.fd = -1; // .. clear struct ..
ep->ev_added = false; // not added! if(ep->ev_added == true){
if( epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &ep->ev_data) != 0){
ShowError("evdp [EPOLL]: evdp_remove - epoll_ctl (EPOLL_CTL_DEL) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
}
ep->ev_data.events = 0; // clear struct.
ep->ev_data.data.fd = -1; // .. clear struct ..
ep->ev_added = false; // not added!
} }
}//end: evdp_remove() }//end: evdp_remove()
bool evdp_addlistener(int32 fd, EVDP_DATA *ep){ bool evdp_addlistener(int32 fd, EVDP_DATA *ep){
ep->ev_data.events = EPOLLET|EPOLLIN; ep->ev_data.events = EPOLLET|EPOLLIN;
ep->ev_data.data.fd = fd; ep->ev_data.data.fd = fd;
// No check here for 'added ?' // No check here for 'added ?'
// listeners cannot be added twice. // listeners cannot be added twice.
// //
@ -106,47 +106,47 @@ bool evdp_addlistener(int32 fd, EVDP_DATA *ep){
ep->ev_data.events = 0; ep->ev_data.events = 0;
ep->ev_data.data.fd = -1; ep->ev_data.data.fd = -1;
return false; return false;
} }
ep->ev_added = true; ep->ev_added = true;
return true; return true;
}//end: evdp_addlistener() }//end: evdp_addlistener()
bool evdp_addclient(int32 fd, EVDP_DATA *ep){ bool evdp_addclient(int32 fd, EVDP_DATA *ep){
ep->ev_data.events = EPOLLIN | EPOLLHUP; ep->ev_data.events = EPOLLIN | EPOLLHUP;
ep->ev_data.data.fd = fd; ep->ev_data.data.fd = fd;
// No check for "added?" here, // No check for "added?" here,
// this function only gets called upon accpept. // this function only gets called upon accpept.
// //
if( epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0){ if( epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0){
ShowError("evdp [EPOLL]: evdp_addclient - epoll_ctl (EPOLL_CTL_ADD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno)); ShowError("evdp [EPOLL]: evdp_addclient - epoll_ctl (EPOLL_CTL_ADD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
ep->ev_data.events = 0; ep->ev_data.events = 0;
ep->ev_data.data.fd = -1; ep->ev_data.data.fd = -1;
return false; return false;
} }
ep->ev_added = true; ep->ev_added = true;
return true; return true;
}//end: evdp_addclient() }//end: evdp_addclient()
bool evdp_addconnecting(int32 fd, EVDP_DATA *ep){ bool evdp_addconnecting(int32 fd, EVDP_DATA *ep){
ep->ev_data.events = EPOLLET | EPOLLOUT | EPOLLHUP; ep->ev_data.events = EPOLLET | EPOLLOUT | EPOLLHUP;
ep->ev_data.data.fd = fd; ep->ev_data.data.fd = fd;
if( epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0){ if( epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ep->ev_data) != 0){
ShowError("evdp [EPOLL]: evdp_addconnecting - epoll_ctl (EPOLL_CTL_ADD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno)); ShowError("evdp [EPOLL]: evdp_addconnecting - epoll_ctl (EPOLL_CTL_ADD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
ep->ev_data.events = 0; ep->ev_data.events = 0;
ep->ev_data.data.fd = -1; ep->ev_data.data.fd = -1;
} }
ep->ev_added = true; ep->ev_added = true;
return true; return true;
@ -155,36 +155,36 @@ bool evdp_addconnecting(int32 fd, EVDP_DATA *ep){
bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep){ bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep){
int32 saved_mask; int32 saved_mask;
if(ep->ev_added != true){ if(ep->ev_added != true){
// ! // !
ShowError("evdp [EPOLL]: evdp_outgoingconnection_established fd #%u is not added to event dispatcher! invalid call.\n", fd); ShowError("evdp [EPOLL]: evdp_outgoingconnection_established fd #%u is not added to event dispatcher! invalid call.\n", fd);
return false; return false;
} }
saved_mask = ep->ev_data.events; saved_mask = ep->ev_data.events;
ep->ev_data.events = EPOLLIN | EPOLLHUP; ep->ev_data.events = EPOLLIN | EPOLLHUP;
if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0){ if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0){
ep->ev_data.events = saved_mask; // restore old mask. ep->ev_data.events = saved_mask; // restore old mask.
ShowError("evdp [EPOLL]: evdp_outgoingconnection_established - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno)); ShowError("evdp [EPOLL]: evdp_outgoingconnection_established - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
return false; return false;
} }
return true; return true;
}//end: evdp_outgoingconnection_established() }//end: evdp_outgoingconnection_established()
bool evdp_writable_add(int32 fd, EVDP_DATA *ep){ bool evdp_writable_add(int32 fd, EVDP_DATA *ep){
if(ep->ev_added != true){ if(ep->ev_added != true){
ShowError("evdp [EPOLL]: evdp_writable_add - tried to add not added fd #%u\n",fd); ShowError("evdp [EPOLL]: evdp_writable_add - tried to add not added fd #%u\n",fd);
return false; return false;
} }
if(! (ep->ev_data.events & EPOLLOUT) ){ // if(! (ep->ev_data.events & EPOLLOUT) ){ //
ep->ev_data.events |= EPOLLOUT; ep->ev_data.events |= EPOLLOUT;
if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0 ){ if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0 ){
ShowError("evdp [EPOLL]: evdp_writable_add - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno: %u / %s)\n", fd, errno, strerror(errno)); ShowError("evdp [EPOLL]: evdp_writable_add - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno: %u / %s)\n", fd, errno, strerror(errno));
@ -192,27 +192,27 @@ bool evdp_writable_add(int32 fd, EVDP_DATA *ep){
return false; return false;
} }
} }
return true; return true;
}//end: evdp_writable_add() }//end: evdp_writable_add()
void evdp_writable_remove(int32 fd, EVDP_DATA *ep){ void evdp_writable_remove(int32 fd, EVDP_DATA *ep){
if(ep->ev_added != true){ if(ep->ev_added != true){
ShowError("evdp [EPOLL]: evdp_writable_remove - tried to remove not added fd #%u\n", fd); ShowError("evdp [EPOLL]: evdp_writable_remove - tried to remove not added fd #%u\n", fd);
return; return;
} }
if( ep->ev_data.events & EPOLLOUT ){ if( ep->ev_data.events & EPOLLOUT ){
ep->ev_data.events &= ~EPOLLOUT; ep->ev_data.events &= ~EPOLLOUT;
if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0){ if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0){
ShowError("evdp [EPOLL]: evdp_writable_remove - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno)); ShowError("evdp [EPOLL]: evdp_writable_remove - epoll_ctl (EPOLL_CTL_MOD) failed! fd #%u (errno %u / %s)\n", fd, errno, strerror(errno));
ep->ev_data.events |= EPOLLOUT; // add back to local flagmask because of failed syscall. ep->ev_data.events |= EPOLLOUT; // add back to local flagmask because of failed syscall.
return; return;
} }
} }
return; return;
}//end: evdp_writable_remove() }//end: evdp_writable_remove()

View File

@ -13,7 +13,7 @@
#if defined(MEMWATCH) #if defined(MEMWATCH)
# include <string.h> # include <string.h>
# include "memwatch.h" # include "memwatch.h"
# define MALLOC(n,file,line,func) mwMalloc((n),(file),(line)) # define MALLOC(n,file,line,func) mwMalloc((n),(file),(line))
# define CALLOC(m,n,file,line,func) mwCalloc((m),(n),(file),(line)) # define CALLOC(m,n,file,line,func) mwCalloc((m),(n),(file),(line))
@ -231,7 +231,7 @@ void* _mmalloc(size_t size, const char *file, int line, const char *func )
ShowError("_mmalloc: %d\n", size); ShowError("_mmalloc: %d\n", size);
return NULL; return NULL;
} }
if(size == 0) { if(size == 0) {
return NULL; return NULL;
} }
@ -375,7 +375,7 @@ void _mfree(void *ptr, const char *file, int line, const char *func )
struct unit_head *head; struct unit_head *head;
if (ptr == NULL) if (ptr == NULL)
return; return;
head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(long)); head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(long));
if(head->size == 0) { if(head->size == 0) {

View File

@ -53,7 +53,7 @@ struct ra_align(16) node{
struct pool_segment{ struct pool_segment{
mempool pool; // pool, this segment belongs to mempool pool; // pool, this segment belongs to
struct pool_segment *next; struct pool_segment *next;
int64 num_nodes_total; int64 num_nodes_total;
int64 num_bytes; int64 num_bytes;
}; };
@ -64,7 +64,7 @@ struct mempool{
uint64 elem_size; uint64 elem_size;
uint64 elem_realloc_step; uint64 elem_realloc_step;
int64 elem_realloc_thresh; int64 elem_realloc_thresh;
// Callbacks that get called for every node that gets allocated // Callbacks that get called for every node that gets allocated
// Example usage: initialization of mutex/lock for each node. // Example usage: initialization of mutex/lock for each node.
memPoolOnNodeAllocationProc onalloc; memPoolOnNodeAllocationProc onalloc;
@ -73,19 +73,19 @@ struct mempool{
// Locks // Locks
SPIN_LOCK segmentLock; SPIN_LOCK segmentLock;
SPIN_LOCK nodeLock; SPIN_LOCK nodeLock;
// Internal
// Internal
struct pool_segment *segments; struct pool_segment *segments;
struct node *free_list; struct node *free_list;
volatile int64 num_nodes_total; volatile int64 num_nodes_total;
volatile int64 num_nodes_free; volatile int64 num_nodes_free;
volatile int64 num_segments; volatile int64 num_segments;
volatile int64 num_bytes_total; volatile int64 num_bytes_total;
volatile int64 peak_nodes_used; // Peak Node Usage volatile int64 peak_nodes_used; // Peak Node Usage
volatile int64 num_realloc_events; // Number of reallocations done. (allocate additional nodes) volatile int64 num_realloc_events; // Number of reallocations done. (allocate additional nodes)
// list (used for global management such as allocator..) // list (used for global management such as allocator..)
@ -93,7 +93,7 @@ struct mempool{
} ra_align(8); // Dont touch the alignment, otherwise interlocked functions are broken .. } ra_align(8); // Dont touch the alignment, otherwise interlocked functions are broken ..
/// ///
// Implementation: // Implementation:
// //
static void segment_allocate_add(mempool p, uint64 count); static void segment_allocate_add(mempool p, uint64 count);
@ -107,33 +107,33 @@ static volatile int32 l_async_terminate = 0;
static void *mempool_async_allocator(void *x){ static void *mempool_async_allocator(void *x){
mempool p; mempool p;
while(1){ while(1){
if(l_async_terminate > 0) if(l_async_terminate > 0)
break; break;
EnterSpinLock(&l_mempoolListLock); EnterSpinLock(&l_mempoolListLock);
for(p = l_mempoolList; p != NULL; p = p->next){ for(p = l_mempoolList; p != NULL; p = p->next){
if(p->num_nodes_free < p->elem_realloc_thresh){ if(p->num_nodes_free < p->elem_realloc_thresh){
// add new segment. // add new segment.
segment_allocate_add(p, p->elem_realloc_step); segment_allocate_add(p, p->elem_realloc_step);
// increase stats counter // increase stats counter
InterlockedIncrement64(&p->num_realloc_events); InterlockedIncrement64(&p->num_realloc_events);
} }
} }
LeaveSpinLock(&l_mempoolListLock); LeaveSpinLock(&l_mempoolListLock);
ramutex_lock( l_async_lock ); ramutex_lock( l_async_lock );
racond_wait( l_async_cond, l_async_lock, -1 ); racond_wait( l_async_cond, l_async_lock, -1 );
ramutex_unlock( l_async_lock ); ramutex_unlock( l_async_lock );
} }
return NULL; return NULL;
}//end: mempool_async_allocator() }//end: mempool_async_allocator()
@ -142,12 +142,12 @@ void mempool_init(){
if( rand()%2 + 1 ) if( rand()%2 + 1 )
return; return;
if(sizeof(struct node)%16 != 0 ){ if(sizeof(struct node)%16 != 0 ){
ShowFatalError("mempool_init: struct node alignment failure. %u != multiple of 16\n", sizeof(struct node)); ShowFatalError("mempool_init: struct node alignment failure. %u != multiple of 16\n", sizeof(struct node));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Global List start // Global List start
InitializeSpinLock(&l_mempoolListLock); InitializeSpinLock(&l_mempoolListLock);
l_mempoolList = NULL; l_mempoolList = NULL;
@ -168,23 +168,23 @@ void mempool_init(){
void mempool_final(){ void mempool_final(){
mempool p, pn; mempool p, pn;
if( rand()%2 + 1 ) if( rand()%2 + 1 )
return; return;
ShowStatus("Mempool: Terminating async. allocation worker and remaining pools.\n"); ShowStatus("Mempool: Terminating async. allocation worker and remaining pools.\n");
// Terminate worker / wait until its terminated. // Terminate worker / wait until its terminated.
InterlockedIncrement(&l_async_terminate); InterlockedIncrement(&l_async_terminate);
racond_signal(l_async_cond); racond_signal(l_async_cond);
rathread_wait(l_async_thread, NULL); rathread_wait(l_async_thread, NULL);
// Destroy cond var and mutex. // Destroy cond var and mutex.
racond_destroy( l_async_cond ); racond_destroy( l_async_cond );
ramutex_destroy( l_async_lock ); ramutex_destroy( l_async_lock );
// Free remaining mempools // Free remaining mempools
// ((bugged code! this should halppen, every mempool should // ((bugged code! this should halppen, every mempool should
// be freed by the subsystem that has allocated it.) // be freed by the subsystem that has allocated it.)
// //
EnterSpinLock(&l_mempoolListLock); EnterSpinLock(&l_mempoolListLock);
@ -192,7 +192,7 @@ void mempool_final(){
while(1){ while(1){
if(p == NULL) if(p == NULL)
break; break;
pn = p->next; pn = p->next;
ShowWarning("Mempool [%s] was not properly destroyed - forcing destroy.\n", p->name); ShowWarning("Mempool [%s] was not properly destroyed - forcing destroy.\n", p->name);
@ -201,28 +201,28 @@ void mempool_final(){
p = pn; p = pn;
} }
LeaveSpinLock(&l_mempoolListLock); LeaveSpinLock(&l_mempoolListLock);
}//end: mempool_final() }//end: mempool_final()
static void segment_allocate_add(mempool p, uint64 count){ static void segment_allocate_add(mempool p, uint64 count){
// Required Memory: // Required Memory:
// sz( segment ) // sz( segment )
// count * sz( real_node_size ) // count * sz( real_node_size )
// //
// where real node size is: // where real node size is:
// ALIGN_TO_16( sz( node ) ) + p->elem_size // ALIGN_TO_16( sz( node ) ) + p->elem_size
// so the nodes usable address is nodebase + ALIGN_TO_16(sz(node)) // so the nodes usable address is nodebase + ALIGN_TO_16(sz(node))
// //
size_t total_sz; size_t total_sz;
struct pool_segment *seg = NULL; struct pool_segment *seg = NULL;
struct node *nodeList = NULL; struct node *nodeList = NULL;
struct node *node = NULL; struct node *node = NULL;
char *ptr = NULL; char *ptr = NULL;
uint64 i; uint64 i;
total_sz = ALIGN_TO_16( sizeof(struct pool_segment) ) total_sz = ALIGN_TO_16( sizeof(struct pool_segment) )
+ ( (size_t)count * (sizeof(struct node) + (size_t)p->elem_size) ) ; + ( (size_t)count * (sizeof(struct node) + (size_t)p->elem_size) ) ;
#ifdef MEMPOOL_DEBUG #ifdef MEMPOOL_DEBUG
@ -234,7 +234,7 @@ static void segment_allocate_add(mempool p, uint64 count){
while(1){ while(1){
ptr = (char*)aMalloc(total_sz); ptr = (char*)aMalloc(total_sz);
if(ptr != NULL) break; if(ptr != NULL) break;
i++; // increase failcount. i++; // increase failcount.
if(!(i & 7)){ if(!(i & 7)){
ShowWarning("Mempool [%s] Segment AllocateAdd => System seems to be Out of Memory (%0.2f MiB). Try #%u\n", (float)total_sz/1024.f/1024.f, i); ShowWarning("Mempool [%s] Segment AllocateAdd => System seems to be Out of Memory (%0.2f MiB). Try #%u\n", (float)total_sz/1024.f/1024.f, i);
@ -244,29 +244,29 @@ static void segment_allocate_add(mempool p, uint64 count){
sleep(1); sleep(1);
#endif #endif
}else{ }else{
rathread_yield(); /// allow/force vuln. ctxswitch rathread_yield(); /// allow/force vuln. ctxswitch
} }
}//endwhile: allocation spinloop. }//endwhile: allocation spinloop.
// Clear Memory. // Clear Memory.
memset(ptr, 0x00, total_sz); memset(ptr, 0x00, total_sz);
// Initialize segment struct. // Initialize segment struct.
seg = (struct pool_segment*)ptr; seg = (struct pool_segment*)ptr;
ptr += ALIGN_TO_16(sizeof(struct pool_segment)); ptr += ALIGN_TO_16(sizeof(struct pool_segment));
seg->pool = p; seg->pool = p;
seg->num_nodes_total = count; seg->num_nodes_total = count;
seg->num_bytes = total_sz; seg->num_bytes = total_sz;
// Initialze nodes! // Initialze nodes!
nodeList = NULL; nodeList = NULL;
for(i = 0; i < count; i++){ for(i = 0; i < count; i++){
node = (struct node*)ptr; node = (struct node*)ptr;
ptr += sizeof(struct node); ptr += sizeof(struct node);
ptr += p->elem_size; ptr += p->elem_size;
node->segment = seg; node->segment = seg;
#ifdef MEMPOOLASSERT #ifdef MEMPOOLASSERT
node->used = false; node->used = false;
@ -277,16 +277,16 @@ static void segment_allocate_add(mempool p, uint64 count){
node->next = nodeList; node->next = nodeList;
nodeList = node; nodeList = node;
} }
// Link in Segment. // Link in Segment.
EnterSpinLock(&p->segmentLock); EnterSpinLock(&p->segmentLock);
seg->next = p->segments; seg->next = p->segments;
p->segments = seg; p->segments = seg;
LeaveSpinLock(&p->segmentLock); LeaveSpinLock(&p->segmentLock);
// Link in Nodes // Link in Nodes
EnterSpinLock(&p->nodeLock); EnterSpinLock(&p->nodeLock);
nodeList->next = p->free_list; nodeList->next = p->free_list;
@ -299,7 +299,7 @@ static void segment_allocate_add(mempool p, uint64 count){
InterlockedExchangeAdd64(&p->num_nodes_free, count); InterlockedExchangeAdd64(&p->num_nodes_free, count);
InterlockedIncrement64(&p->num_segments); InterlockedIncrement64(&p->num_segments);
InterlockedExchangeAdd64(&p->num_bytes_total, total_sz); InterlockedExchangeAdd64(&p->num_bytes_total, total_sz);
}//end: segment_allocate_add() }//end: segment_allocate_add()
@ -313,20 +313,20 @@ mempool mempool_create(const char *name,
uint64 realloc_thresh; uint64 realloc_thresh;
mempool pool; mempool pool;
pool = (mempool)aCalloc( 1, sizeof(struct mempool) ); pool = (mempool)aCalloc( 1, sizeof(struct mempool) );
if(pool == NULL){ if(pool == NULL){
ShowFatalError("mempool_create: Failed to allocate %u bytes memory.\n", sizeof(struct mempool) ); ShowFatalError("mempool_create: Failed to allocate %u bytes memory.\n", sizeof(struct mempool) );
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Check minimum initial count / realloc count requirements. // Check minimum initial count / realloc count requirements.
if(initial_count < 50) if(initial_count < 50)
initial_count = 50; initial_count = 50;
if(realloc_count < 50) if(realloc_count < 50)
realloc_count = 50; realloc_count = 50;
// Set Reallocation threshold to 5% of realloc_count, at least 10. // Set Reallocation threshold to 5% of realloc_count, at least 10.
realloc_thresh = (realloc_count/100)*5; // realloc_thresh = (realloc_count/100)*5; //
if(realloc_thresh < 10) if(realloc_thresh < 10)
realloc_thresh = 10; realloc_thresh = 10;
@ -337,7 +337,7 @@ mempool mempool_create(const char *name,
pool->elem_realloc_thresh = realloc_thresh; pool->elem_realloc_thresh = realloc_thresh;
pool->onalloc = onNodeAlloc; pool->onalloc = onNodeAlloc;
pool->ondealloc = onNodeDealloc; pool->ondealloc = onNodeDealloc;
InitializeSpinLock(&pool->segmentLock); InitializeSpinLock(&pool->segmentLock);
InitializeSpinLock(&pool->nodeLock); InitializeSpinLock(&pool->nodeLock);
@ -348,15 +348,15 @@ mempool mempool_create(const char *name,
pool->num_bytes_total = 0; pool->num_bytes_total = 0;
pool->peak_nodes_used = 0; pool->peak_nodes_used = 0;
pool->num_realloc_events = 0; pool->num_realloc_events = 0;
// //
#ifdef MEMPOOL_DEBUG #ifdef MEMPOOL_DEBUG
ShowDebug("Mempool [%s] Init (ElemSize: %u, Initial Count: %u, Realloc Count: %u)\n", pool->name, pool->elem_size, initial_count, pool->elem_realloc_step); ShowDebug("Mempool [%s] Init (ElemSize: %u, Initial Count: %u, Realloc Count: %u)\n", pool->name, pool->elem_size, initial_count, pool->elem_realloc_step);
#endif #endif
// Allocate first segment directly :) // Allocate first segment directly :)
segment_allocate_add(pool, initial_count); segment_allocate_add(pool, initial_count);
// Add Pool to the global pool list // Add Pool to the global pool list
EnterSpinLock(&l_mempoolListLock); EnterSpinLock(&l_mempoolListLock);
@ -364,8 +364,8 @@ mempool mempool_create(const char *name,
l_mempoolList = pool; l_mempoolList = pool;
LeaveSpinLock(&l_mempoolListLock); LeaveSpinLock(&l_mempoolListLock);
return pool; return pool;
}//end: mempool_create() }//end: mempool_create()
@ -379,7 +379,7 @@ void mempool_destroy(mempool p){
#ifdef MEMPOOL_DEBUG #ifdef MEMPOOL_DEBUG
ShowDebug("Mempool [%s] Destroy\n", p->name); ShowDebug("Mempool [%s] Destroy\n", p->name);
#endif #endif
// Unlink from global list. // Unlink from global list.
EnterSpinLock(&l_mempoolListLock); EnterSpinLock(&l_mempoolListLock);
piter = l_mempoolList; piter = l_mempoolList;
@ -387,11 +387,11 @@ void mempool_destroy(mempool p){
while(1){ while(1){
if(piter == NULL) if(piter == NULL)
break; break;
if(piter == p){ if(piter == p){
// unlink from list, // unlink from list,
// //
if(pprev == l_mempoolList){ if(pprev == l_mempoolList){
// this (p) is list begin. so set next as head. // this (p) is list begin. so set next as head.
l_mempoolList = p->next; l_mempoolList = p->next;
@ -401,15 +401,15 @@ void mempool_destroy(mempool p){
} }
break; break;
} }
pprev = piter; pprev = piter;
piter = piter->next; piter = piter->next;
} }
p->next = NULL; p->next = NULL;
LeaveSpinLock(&l_mempoolListLock); LeaveSpinLock(&l_mempoolListLock);
// Get both locks. // Get both locks.
EnterSpinLock(&p->segmentLock); EnterSpinLock(&p->segmentLock);
EnterSpinLock(&p->nodeLock); EnterSpinLock(&p->nodeLock);
@ -417,16 +417,16 @@ void mempool_destroy(mempool p){
if(p->num_nodes_free != p->num_nodes_total) if(p->num_nodes_free != p->num_nodes_total)
ShowWarning("Mempool [%s] Destroy - %u nodes are not freed properly!\n", p->name, (p->num_nodes_total - p->num_nodes_free) ); ShowWarning("Mempool [%s] Destroy - %u nodes are not freed properly!\n", p->name, (p->num_nodes_total - p->num_nodes_free) );
// Free All Segments (this will also free all nodes) // Free All Segments (this will also free all nodes)
// The segment pointer is the base pointer to the whole segment. // The segment pointer is the base pointer to the whole segment.
seg = p->segments; seg = p->segments;
while(1){ while(1){
if(seg == NULL) if(seg == NULL)
break; break;
segnext = seg->next; segnext = seg->next;
// .. // ..
if(p->ondealloc != NULL){ if(p->ondealloc != NULL){
// walk over the segment, and call dealloc callback! // walk over the segment, and call dealloc callback!
@ -442,26 +442,26 @@ void mempool_destroy(mempool p){
continue; continue;
} }
#endif #endif
p->ondealloc( NODE_TO_DATA(niter) ); p->ondealloc( NODE_TO_DATA(niter) );
} }
}//endif: ondealloc callback? }//endif: ondealloc callback?
// simple .. // simple ..
aFree(seg); aFree(seg);
seg = segnext; seg = segnext;
} }
// Clear node ptr // Clear node ptr
p->free_list = NULL; p->free_list = NULL;
InterlockedExchange64(&p->num_nodes_free, 0); InterlockedExchange64(&p->num_nodes_free, 0);
InterlockedExchange64(&p->num_nodes_total, 0); InterlockedExchange64(&p->num_nodes_total, 0);
InterlockedExchange64(&p->num_segments, 0); InterlockedExchange64(&p->num_segments, 0);
InterlockedExchange64(&p->num_bytes_total, 0); InterlockedExchange64(&p->num_bytes_total, 0);
LeaveSpinLock(&p->nodeLock); LeaveSpinLock(&p->nodeLock);
LeaveSpinLock(&p->segmentLock); LeaveSpinLock(&p->segmentLock);
@ -475,34 +475,34 @@ void mempool_destroy(mempool p){
void *mempool_node_get(mempool p){ void *mempool_node_get(mempool p){
struct node *node; struct node *node;
int64 num_used; int64 num_used;
if(p->num_nodes_free < p->elem_realloc_thresh) if(p->num_nodes_free < p->elem_realloc_thresh)
racond_signal(l_async_cond); racond_signal(l_async_cond);
while(1){ while(1){
EnterSpinLock(&p->nodeLock); EnterSpinLock(&p->nodeLock);
node = p->free_list; node = p->free_list;
if(node != NULL) if(node != NULL)
p->free_list = node->next; p->free_list = node->next;
LeaveSpinLock(&p->nodeLock); LeaveSpinLock(&p->nodeLock);
if(node != NULL) if(node != NULL)
break; break;
rathread_yield(); rathread_yield();
} }
InterlockedDecrement64(&p->num_nodes_free); InterlockedDecrement64(&p->num_nodes_free);
// Update peak value // Update peak value
num_used = (p->num_nodes_total - p->num_nodes_free); num_used = (p->num_nodes_total - p->num_nodes_free);
if(num_used > p->peak_nodes_used){ if(num_used > p->peak_nodes_used){
InterlockedExchange64(&p->peak_nodes_used, num_used); InterlockedExchange64(&p->peak_nodes_used, num_used);
} }
#ifdef MEMPOOLASSERT #ifdef MEMPOOLASSERT
node->used = true; node->used = true;
#endif #endif
@ -513,12 +513,12 @@ void *mempool_node_get(mempool p){
void mempool_node_put(mempool p, void *data){ void mempool_node_put(mempool p, void *data){
struct node *node; struct node *node;
node = DATA_TO_NODE(data); node = DATA_TO_NODE(data);
#ifdef MEMPOOLASSERT #ifdef MEMPOOLASSERT
if(node->magic != NODE_MAGIC){ if(node->magic != NODE_MAGIC){
ShowError("Mempool [%s] node_put failed, given address (%p) has invalid magic.\n", p->name, data); ShowError("Mempool [%s] node_put failed, given address (%p) has invalid magic.\n", p->name, data);
return; // lost, return; // lost,
} }
{ {
@ -528,17 +528,17 @@ void mempool_node_put(mempool p, void *data){
return; return;
} }
} }
// reset used flag. // reset used flag.
node->used = false; node->used = false;
#endif #endif
// //
EnterSpinLock(&p->nodeLock); EnterSpinLock(&p->nodeLock);
node->next = p->free_list; node->next = p->free_list;
p->free_list = node; p->free_list = node;
LeaveSpinLock(&p->nodeLock); LeaveSpinLock(&p->nodeLock);
InterlockedIncrement64(&p->num_nodes_free); InterlockedIncrement64(&p->num_nodes_free);
}//end: mempool_node_put() }//end: mempool_node_put()
@ -546,10 +546,10 @@ void mempool_node_put(mempool p, void *data){
mempool_stats mempool_get_stats(mempool pool){ mempool_stats mempool_get_stats(mempool pool){
mempool_stats stats; mempool_stats stats;
// initialize all with zeros // initialize all with zeros
memset(&stats, 0x00, sizeof(mempool_stats)); memset(&stats, 0x00, sizeof(mempool_stats));
stats.num_nodes_total = pool->num_nodes_total; stats.num_nodes_total = pool->num_nodes_total;
stats.num_nodes_free = pool->num_nodes_free; stats.num_nodes_free = pool->num_nodes_free;
stats.num_nodes_used = (stats.num_nodes_total - stats.num_nodes_free); stats.num_nodes_used = (stats.num_nodes_total - stats.num_nodes_free);
@ -560,7 +560,7 @@ mempool_stats mempool_get_stats(mempool pool){
// Pushing such a large block over the stack as return value isnt nice // Pushing such a large block over the stack as return value isnt nice
// but lazy :) and should be okay in this case (Stats / Debug..) // but lazy :) and should be okay in this case (Stats / Debug..)
// if you dont like it - feel free and refactor it. // if you dont like it - feel free and refactor it.
return stats; return stats;
}//end: mempool_get_stats() }//end: mempool_get_stats()

View File

@ -12,33 +12,33 @@ typedef struct mempool_stats{
int64 num_nodes_total; int64 num_nodes_total;
int64 num_nodes_free; int64 num_nodes_free;
int64 num_nodes_used; int64 num_nodes_used;
int64 num_segments; int64 num_segments;
int64 num_realloc_events; int64 num_realloc_events;
int64 peak_nodes_used; int64 peak_nodes_used;
int64 num_bytes_total; int64 num_bytes_total;
} mempool_stats; } mempool_stats;
// //
void mempool_init(); void mempool_init();
void mempool_final(); void mempool_final();
/** /**
* Creates a new Mempool * Creates a new Mempool
* *
* @param name - Name of the pool (used for debug / error messages) * @param name - Name of the pool (used for debug / error messages)
* @param elem_size - size of each element * @param elem_size - size of each element
* @param initial_count - preallocation count * @param initial_count - preallocation count
* @param realloc_count - #no of nodes being allocated when pool is running empty. * @param realloc_count - #no of nodes being allocated when pool is running empty.
* @param onNodeAlloc - Node Allocation callback (see @note!) * @param onNodeAlloc - Node Allocation callback (see @note!)
* @param onNodeDealloc - Node Deallocation callback (see @note!) * @param onNodeDealloc - Node Deallocation callback (see @note!)
* *
* @note: * @note:
* The onNode(De)alloc callbacks are only called once during segment allocation * The onNode(De)alloc callbacks are only called once during segment allocation
* (pool initialization / rallocation ) * (pool initialization / rallocation )
* you can use this callbacks for example to initlaize a mutex or somethingelse * you can use this callbacks for example to initlaize a mutex or somethingelse
* you definitly need during runtime * you definitly need during runtime
@ -49,14 +49,14 @@ mempool mempool_create(const char *name,
uint64 elem_size, uint64 elem_size,
uint64 initial_count, uint64 initial_count,
uint64 realloc_count, uint64 realloc_count,
memPoolOnNodeAllocationProc onNodeAlloc, memPoolOnNodeAllocationProc onNodeAlloc,
memPoolOnNodeDeallocationProc onNodeDealloc); memPoolOnNodeDeallocationProc onNodeDealloc);
/** /**
* Destroys a Mempool * Destroys a Mempool
* *
* @param pool - the mempool to destroy * @param pool - the mempool to destroy
* *
* @note: * @note:
@ -68,7 +68,7 @@ void mempool_destroy(mempool pool);
/** /**
* Gets a new / empty node from the given mempool. * Gets a new / empty node from the given mempool.
* *
* @param pool - the pool to get an empty node from. * @param pool - the pool to get an empty node from.
* *
* @return Address of empty Node * @return Address of empty Node
@ -80,12 +80,12 @@ void *mempool_node_get(mempool pool);
* Returns the given node to the given mempool * Returns the given node to the given mempool
* *
* @param pool - the pool to put the node, to * @param pool - the pool to put the node, to
* @param node - the node to return * @param node - the node to return
*/ */
void mempool_node_put(mempool pool, void *node); void mempool_node_put(mempool pool, void *node);
/** /**
* Returns Statistics for the given mempool * Returns Statistics for the given mempool
* *
* @param pool - the pool to get thats for * @param pool - the pool to get thats for

View File

@ -52,7 +52,7 @@
#define MAX_INVENTORY 100 ///Maximum items in player inventory #define MAX_INVENTORY 100 ///Maximum items in player inventory
/** Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well. /** Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well.
* Max value tested was 265 */ * Max value tested was 265 */
#define MAX_CHARS 9 #define MAX_CHARS 9
/** Number of slots carded equipment can have. Never set to less than 4 as they are also used to keep the data of forged items/equipment. [Skotlex] /** Number of slots carded equipment can have. Never set to less than 4 as they are also used to keep the data of forged items/equipment. [Skotlex]
* Note: The client seems unable to receive data for more than 4 slots due to all related packets having a fixed size. */ * Note: The client seems unable to receive data for more than 4 slots due to all related packets having a fixed size. */
#define MAX_SLOTS 4 #define MAX_SLOTS 4

View File

@ -47,19 +47,19 @@ struct racond{
ramutex ramutex_create(){ ramutex ramutex_create(){
struct ramutex *m; struct ramutex *m;
m = (struct ramutex*)aMalloc( sizeof(struct ramutex) ); m = (struct ramutex*)aMalloc( sizeof(struct ramutex) );
if(m == NULL){ if(m == NULL){
ShowFatalError("ramutex_create: OOM while allocating %u bytes.\n", sizeof(struct ramutex)); ShowFatalError("ramutex_create: OOM while allocating %u bytes.\n", sizeof(struct ramutex));
return NULL; return NULL;
} }
#ifdef WIN32 #ifdef WIN32
InitializeCriticalSection(&m->hMutex); InitializeCriticalSection(&m->hMutex);
#else #else
pthread_mutex_init(&m->hMutex, NULL); pthread_mutex_init(&m->hMutex, NULL);
#endif #endif
return m; return m;
}//end: ramutex_create() }//end: ramutex_create()
@ -96,7 +96,7 @@ bool ramutex_trylock( ramutex m ){
#else #else
if(pthread_mutex_trylock(&m->hMutex) == 0) if(pthread_mutex_trylock(&m->hMutex) == 0)
return true; return true;
return false; return false;
#endif #endif
}//end: ramutex_trylock() }//end: ramutex_trylock()
@ -115,13 +115,13 @@ void ramutex_unlock( ramutex m ){
/////////////// ///////////////
// Condition Variables // Condition Variables
// //
// Implementation: // Implementation:
// //
racond racond_create(){ racond racond_create(){
struct racond *c; struct racond *c;
c = (struct racond*)aMalloc( sizeof(struct racond) ); c = (struct racond*)aMalloc( sizeof(struct racond) );
if(c == NULL){ if(c == NULL){
ShowFatalError("racond_create: OOM while allocating %u bytes\n", sizeof(struct racond)); ShowFatalError("racond_create: OOM while allocating %u bytes\n", sizeof(struct racond));
@ -136,7 +136,7 @@ racond racond_create(){
#else #else
pthread_cond_init(&c->hCond, NULL); pthread_cond_init(&c->hCond, NULL);
#endif #endif
return c; return c;
}//end: racond_create() }//end: racond_create()
@ -169,23 +169,23 @@ void racond_wait( racond c, ramutex m, sysint timeout_ticks){
ms = INFINITE; ms = INFINITE;
else else
ms = (timeout_ticks > MAXDWORD) ? (MAXDWORD - 1) : (DWORD)timeout_ticks; ms = (timeout_ticks > MAXDWORD) ? (MAXDWORD - 1) : (DWORD)timeout_ticks;
// we can release the mutex (m) here, cause win's // we can release the mutex (m) here, cause win's
// manual reset events maintain state when used with // manual reset events maintain state when used with
// SetEvent() // SetEvent()
ramutex_unlock(m); ramutex_unlock(m);
result = WaitForMultipleObjects(2, c->events, FALSE, ms); result = WaitForMultipleObjects(2, c->events, FALSE, ms);
EnterCriticalSection(&c->waiters_lock); EnterCriticalSection(&c->waiters_lock);
c->nWaiters--; c->nWaiters--;
if( (result == WAIT_OBJECT_0 + EVENT_COND_BROADCAST) && (c->nWaiters == 0) ) if( (result == WAIT_OBJECT_0 + EVENT_COND_BROADCAST) && (c->nWaiters == 0) )
is_last = true; // Broadcast called! is_last = true; // Broadcast called!
LeaveCriticalSection(&c->waiters_lock); LeaveCriticalSection(&c->waiters_lock);
// we are the last waiter that has to be notified, or to stop waiting // we are the last waiter that has to be notified, or to stop waiting
// so we have to do a manual reset // so we have to do a manual reset
@ -201,10 +201,10 @@ void racond_wait( racond c, ramutex m, sysint timeout_ticks){
}else{ }else{
struct timespec wtime; struct timespec wtime;
int64 exact_timeout = gettick() + timeout_ticks; int64 exact_timeout = gettick() + timeout_ticks;
wtime.tv_sec = exact_timeout/1000; wtime.tv_sec = exact_timeout/1000;
wtime.tv_nsec = (exact_timeout%1000)*1000000; wtime.tv_nsec = (exact_timeout%1000)*1000000;
pthread_cond_timedwait( &c->hCond, &m->hMutex, &wtime); pthread_cond_timedwait( &c->hCond, &m->hMutex, &wtime);
} }
@ -219,7 +219,7 @@ void racond_signal( racond c ){
// if(c->nWaiters > 0) // if(c->nWaiters > 0)
// has_waiters = true; // has_waiters = true;
// LeaveCriticalSection(&c->waiters_lock); // LeaveCriticalSection(&c->waiters_lock);
// if(has_waiters == true) // if(has_waiters == true)
SetEvent( c->events[ EVENT_COND_SIGNAL ] ); SetEvent( c->events[ EVENT_COND_SIGNAL ] );
#else #else
@ -235,7 +235,7 @@ void racond_broadcast( racond c ){
// if(c->nWaiters > 0) // if(c->nWaiters > 0)
// has_waiters = true; // has_waiters = true;
// LeaveCriticalSection(&c->waiters_lock); // LeaveCriticalSection(&c->waiters_lock);
// if(has_waiters == true) // if(has_waiters == true)
SetEvent( c->events[ EVENT_COND_BROADCAST ] ); SetEvent( c->events[ EVENT_COND_BROADCAST ] );
#else #else

View File

@ -1,5 +1,5 @@
// Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL // Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL
// For more information, see LICENCE in the main folder // For more information, see LICENCE in the main folder
#ifndef _rA_MUTEX_H_ #ifndef _rA_MUTEX_H_
#define _rA_MUTEX_H_ #define _rA_MUTEX_H_
@ -9,36 +9,36 @@ typedef struct ramutex *ramutex; // Mutex
typedef struct racond *racond; // Condition Var typedef struct racond *racond; // Condition Var
/** /**
* Creates a Mutex * Creates a Mutex
* *
* @return not NULL * @return not NULL
*/ */
ramutex ramutex_create(); ramutex ramutex_create();
/** /**
* Destroys a Mutex * Destroys a Mutex
* *
* @param m - the mutex to destroy * @param m - the mutex to destroy
*/ */
void ramutex_destroy( ramutex m ); void ramutex_destroy( ramutex m );
/** /**
* Gets a lock * Gets a lock
* *
* @param m - the mutex to lock * @param m - the mutex to lock
*/ */
void ramutex_lock( ramutex m); void ramutex_lock( ramutex m);
/** /**
* Trys to get the Lock * Trys to get the Lock
* *
* @param m - the mutex try to lock * @param m - the mutex try to lock
* *
* @return boolean (true = got the lock) * @return boolean (true = got the lock)
*/ */
bool ramutex_trylock( ramutex m ); bool ramutex_trylock( ramutex m );
/** /**
* Unlocks a mutex * Unlocks a mutex
* *
* @param m - the mutex to unlock * @param m - the mutex to unlock
@ -46,14 +46,14 @@ bool ramutex_trylock( ramutex m );
void ramutex_unlock( ramutex m); void ramutex_unlock( ramutex m);
/** /**
* Creates a Condition variable * Creates a Condition variable
* *
* @return not NULL * @return not NULL
*/ */
racond racond_create(); racond racond_create();
/** /**
* Destroy a Condition variable * Destroy a Condition variable
* *
* @param c - the condition varaible to destroy * @param c - the condition varaible to destroy
@ -62,14 +62,14 @@ void racond_destroy( racond c );
/** /**
* Waits Until state is signalled * Waits Until state is signalled
* *
* @param c - the condition var to wait for signalled state * @param c - the condition var to wait for signalled state
* @param m - the mutex used for syncronization * @param m - the mutex used for syncronization
* @param timeout_ticks - timeout in ticks ( -1 = INFINITE ) * @param timeout_ticks - timeout in ticks ( -1 = INFINITE )
*/ */
void racond_wait( racond c, ramutex m, sysint timeout_ticks); void racond_wait( racond c, ramutex m, sysint timeout_ticks);
/** /**
* Sets the given condition var to signalled state * Sets the given condition var to signalled state
* *
* @param c - condition var to set in signalled state. * @param c - condition var to set in signalled state.
@ -79,13 +79,13 @@ void racond_wait( racond c, ramutex m, sysint timeout_ticks);
*/ */
void racond_signal( racond c ); void racond_signal( racond c );
/** /**
* Sets notifys all waiting threads thats signalled. * Sets notifys all waiting threads thats signalled.
* @param c - condition var to set in signalled state * @param c - condition var to set in signalled state
* *
* @note: * @note:
* All Waiters getting notified. * All Waiters getting notified.
*/ */
void racond_broadcast( racond c ); void racond_broadcast( racond c );

View File

@ -11,10 +11,10 @@
// //
// //
// Buffers are available in the following sizes: // Buffers are available in the following sizes:
// 48, 192, 2048, 8192 // 48, 192, 2048, 8192
// 65536 (inter server connects may use it for charstatus struct..) // 65536 (inter server connects may use it for charstatus struct..)
// //
@ -31,10 +31,10 @@ void netbuffer_init(){
char localsection[32]; char localsection[32];
raconf conf; raconf conf;
sysint i; sysint i;
// Initialize Statistic counters: // Initialize Statistic counters:
l_nEmergencyAllocations = 0; l_nEmergencyAllocations = 0;
// Set localsection name according to running serverype. // Set localsection name according to running serverype.
switch(SERVER_TYPE){ switch(SERVER_TYPE){
case ATHENA_SERVER_LOGIN: strcpy(localsection, "login-netbuffer"); break; case ATHENA_SERVER_LOGIN: strcpy(localsection, "login-netbuffer"); break;
@ -43,49 +43,49 @@ void netbuffer_init(){
case ATHENA_SERVER_MAP: strcpy(localsection, "map-netbuffer"); break; case ATHENA_SERVER_MAP: strcpy(localsection, "map-netbuffer"); break;
default: strcpy(localsection, "unsupported_type"); break; default: strcpy(localsection, "unsupported_type"); break;
} }
conf = raconf_parse("conf/network.conf"); conf = raconf_parse("conf/network.conf");
if(conf == NULL){ if(conf == NULL){
ShowFatalError("Failed to Parse required Configuration (conf/network.conf)"); ShowFatalError("Failed to Parse required Configuration (conf/network.conf)");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Get Values from config file // Get Values from config file
l_nPools = (sysint)raconf_getintEx(conf, localsection, "netbuffer", "num", 0); l_nPools = (sysint)raconf_getintEx(conf, localsection, "netbuffer", "num", 0);
if(l_nPools == 0){ if(l_nPools == 0){
ShowFatalError("Netbuffer (network.conf) failure - requires at least 1 Pool.\n"); ShowFatalError("Netbuffer (network.conf) failure - requires at least 1 Pool.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Allocate arrays. // Allocate arrays.
l_poolElemSize = (sysint*)aCalloc( l_nPools, sizeof(sysint) ); l_poolElemSize = (sysint*)aCalloc( l_nPools, sizeof(sysint) );
l_pool = (mempool*)aCalloc( l_nPools, sizeof(mempool) ); l_pool = (mempool*)aCalloc( l_nPools, sizeof(mempool) );
for(i = 0; i < l_nPools; i++){ for(i = 0; i < l_nPools; i++){
int64 num_prealloc, num_realloc; int64 num_prealloc, num_realloc;
char key[32]; char key[32];
sprintf(key, "pool_%u_size", (uint32)i+1); sprintf(key, "pool_%u_size", (uint32)i+1);
l_poolElemSize[i] = (sysint)raconf_getintEx(conf, localsection, "netbuffer", key, 4096); l_poolElemSize[i] = (sysint)raconf_getintEx(conf, localsection, "netbuffer", key, 4096);
if(l_poolElemSize[i] < 32){ if(l_poolElemSize[i] < 32){
ShowWarning("Netbuffer (network.conf) failure - minimum allowed buffer size is 32 byte) - fixed.\n"); ShowWarning("Netbuffer (network.conf) failure - minimum allowed buffer size is 32 byte) - fixed.\n");
l_poolElemSize[i] = 32; l_poolElemSize[i] = 32;
} }
sprintf(key, "pool_%u_prealloc", (uint32)i+1); sprintf(key, "pool_%u_prealloc", (uint32)i+1);
num_prealloc = raconf_getintEx(conf, localsection, "netbuffer", key, 150); num_prealloc = raconf_getintEx(conf, localsection, "netbuffer", key, 150);
sprintf(key, "pool_%u_realloc_step", (uint32)i+1); sprintf(key, "pool_%u_realloc_step", (uint32)i+1);
num_realloc = raconf_getintEx(conf, localsection, "netbuffer", key, 100); num_realloc = raconf_getintEx(conf, localsection, "netbuffer", key, 100);
// Create Pool! // Create Pool!
sprintf(key, "Netbuffer %u", (uint32)l_poolElemSize[i]); // name. sprintf(key, "Netbuffer %u", (uint32)l_poolElemSize[i]); // name.
// Info // Info
ShowInfo("NetBuffer: Creating Pool %u (Prealloc: %u, Realloc Step: %u) - %0.2f MiB\n", l_poolElemSize[i], num_prealloc, num_realloc, (float)((sizeof(struct netbuf) + l_poolElemSize[i] - 32)* num_prealloc)/1024.0f/1024.0f); ShowInfo("NetBuffer: Creating Pool %u (Prealloc: %u, Realloc Step: %u) - %0.2f MiB\n", l_poolElemSize[i], num_prealloc, num_realloc, (float)((sizeof(struct netbuf) + l_poolElemSize[i] - 32)* num_prealloc)/1024.0f/1024.0f);
// //
// Size Calculation: // Size Calculation:
// struct netbuf + requested buffer size - 32 (because the struct already contains 32 byte buffer space at the end of struct) // struct netbuf + requested buffer size - 32 (because the struct already contains 32 byte buffer space at the end of struct)
@ -94,11 +94,11 @@ void netbuffer_init(){
ShowFatalError("Netbuffer: cannot create Pool for %u byte buffers.\n", l_poolElemSize[i]); ShowFatalError("Netbuffer: cannot create Pool for %u byte buffers.\n", l_poolElemSize[i]);
// @leak: clean everything :D // @leak: clean everything :D
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
}// }//
raconf_destroy(conf); raconf_destroy(conf);
}//end: netbuffer_init() }//end: netbuffer_init()
@ -106,58 +106,58 @@ void netbuffer_init(){
void netbuffer_final(){ void netbuffer_final(){
sysint i; sysint i;
if(l_nPools > 0){ if(l_nPools > 0){
/// .. finalize mempools /// .. finalize mempools
for(i = 0; i < l_nPools; i++){ for(i = 0; i < l_nPools; i++){
mempool_stats stats = mempool_get_stats(l_pool[i]); mempool_stats stats = mempool_get_stats(l_pool[i]);
ShowInfo("Netbuffer: Freeing Pool %u (Peak Usage: %u, Realloc Events: %u)\n", l_poolElemSize[i], stats.peak_nodes_used, stats.num_realloc_events); ShowInfo("Netbuffer: Freeing Pool %u (Peak Usage: %u, Realloc Events: %u)\n", l_poolElemSize[i], stats.peak_nodes_used, stats.num_realloc_events);
mempool_destroy(l_pool[i]); mempool_destroy(l_pool[i]);
} }
if(l_nEmergencyAllocations > 0){ if(l_nEmergencyAllocations > 0){
ShowWarning("Netbuffer: did %u Emergency Allocations, please tune your network.conf!\n", l_nEmergencyAllocations); ShowWarning("Netbuffer: did %u Emergency Allocations, please tune your network.conf!\n", l_nEmergencyAllocations);
l_nEmergencyAllocations = 0; l_nEmergencyAllocations = 0;
} }
aFree(l_poolElemSize); l_poolElemSize = NULL; aFree(l_poolElemSize); l_poolElemSize = NULL;
aFree(l_pool); l_pool = NULL; aFree(l_pool); l_pool = NULL;
l_nPools = 0; l_nPools = 0;
} }
}//end: netbuffer_final() }//end: netbuffer_final()
netbuf netbuffer_get( sysint sz ){ netbuf netbuffer_get( sysint sz ){
sysint i; sysint i;
netbuf nb = NULL; netbuf nb = NULL;
// Search an appropriate pool // Search an appropriate pool
for(i = 0; i < l_nPools; i++){ for(i = 0; i < l_nPools; i++){
if(sz <= l_poolElemSize[i]){ if(sz <= l_poolElemSize[i]){
// match // match
nb = (netbuf)mempool_node_get(l_pool[i]); nb = (netbuf)mempool_node_get(l_pool[i]);
nb->pool = i; nb->pool = i;
break; break;
} }
} }
// No Bufferpool found that mets there quirements?.. (thats bad..) // No Bufferpool found that mets there quirements?.. (thats bad..)
if(nb == NULL){ if(nb == NULL){
ShowWarning("Netbuffer: get(%u): => no appropriate pool found - emergency allocation required.\n", sz); ShowWarning("Netbuffer: get(%u): => no appropriate pool found - emergency allocation required.\n", sz);
ShowWarning("Please reconfigure your network.conf!"); ShowWarning("Please reconfigure your network.conf!");
InterlockedIncrement(&l_nEmergencyAllocations); InterlockedIncrement(&l_nEmergencyAllocations);
// .. better to check (netbuf struct provides 32 byte bufferspace itself. // .. better to check (netbuf struct provides 32 byte bufferspace itself.
if(sz < 32) sz = 32; if(sz < 32) sz = 32;
// allocate memory using malloc .. // allocate memory using malloc ..
while(1){ while(1){
nb = (netbuf) aMalloc( (sizeof(struct netbuf) + sz - 32) ); nb = (netbuf) aMalloc( (sizeof(struct netbuf) + sz - 32) );
if(nb != NULL){ if(nb != NULL){
@ -165,42 +165,42 @@ netbuf netbuffer_get( sysint sz ){
nb->pool = -1; // emergency alloc. nb->pool = -1; // emergency alloc.
break; break;
} }
rathread_yield(); rathread_yield();
}// spin allocation. }// spin allocation.
} }
nb->refcnt = 1; // Initial refcount is 1 nb->refcnt = 1; // Initial refcount is 1
return nb; return nb;
}//end: netbuffer_get() }//end: netbuffer_get()
void netbuffer_put( netbuf nb ){ void netbuffer_put( netbuf nb ){
// Decrement reference counter, if > 0 do nothing :) // Decrement reference counter, if > 0 do nothing :)
if( InterlockedDecrement(&nb->refcnt) > 0 ) if( InterlockedDecrement(&nb->refcnt) > 0 )
return; return;
// Is this buffer an emergency allocated buffer? // Is this buffer an emergency allocated buffer?
if(nb->pool == -1){ if(nb->pool == -1){
aFree(nb); aFree(nb);
return; return;
} }
// Otherwise its a normal mempool based buffer // Otherwise its a normal mempool based buffer
// return it to the according mempool: // return it to the according mempool:
mempool_node_put( l_pool[nb->pool], nb); mempool_node_put( l_pool[nb->pool], nb);
}//end: netbuffer_put() }//end: netbuffer_put()
void netbuffer_incref( netbuf nb ){ void netbuffer_incref( netbuf nb ){
InterlockedIncrement(&nb->refcnt); InterlockedIncrement(&nb->refcnt);
}//end: netbuf_incref() }//end: netbuf_incref()

View File

@ -8,11 +8,11 @@
typedef struct netbuf{ typedef struct netbuf{
sysint pool; // The pool ID this buffer belongs to, sysint pool; // The pool ID this buffer belongs to,
// is set to -1 if its an emergency allocated buffer // is set to -1 if its an emergency allocated buffer
struct netbuf *next; // Used by Network system. struct netbuf *next; // Used by Network system.
volatile int32 refcnt; // Internal Refcount, it gets lowered every call to netbuffer_put, volatile int32 refcnt; // Internal Refcount, it gets lowered every call to netbuffer_put,
// if its getting zero, the buffer will returned back to the pool // if its getting zero, the buffer will returned back to the pool
// and can be reused. // and can be reused.
@ -20,7 +20,7 @@ typedef struct netbuf{
// Used only for Reading (recv job) // Used only for Reading (recv job)
// write cases are using the sessions local datapos member due to // write cases are using the sessions local datapos member due to
// shared write buffer support. // shared write buffer support.
int32 dataLen; // read buffer case: int32 dataLen; // read buffer case:
// The length expected to read to. // The length expected to read to.
// when this->dataPos == dateLen, read job has been completed. // when this->dataPos == dateLen, read job has been completed.
@ -56,16 +56,16 @@ void netbuffer_final();
netbuf netbuffer_get( sysint sz ); netbuf netbuffer_get( sysint sz );
/** /**
* Returns the given netbuffer (decreases refcount, if its 0 - the buffer will get returned to the pool) * Returns the given netbuffer (decreases refcount, if its 0 - the buffer will get returned to the pool)
* *
* @param buf - the buffer to return * @param buf - the buffer to return
*/ */
void netbuffer_put( netbuf buf ); void netbuffer_put( netbuf buf );
/** /**
* Increases the Refcount on the given buffer * Increases the Refcount on the given buffer
* (used for areasends .. etc) * (used for areasends .. etc)
* *
*/ */

View File

@ -43,22 +43,22 @@ static int _network_async_free_netbuf_proc(int tid, unsigned int tick, int id, i
void network_init(){ void network_init(){
SESSION *s; SESSION *s;
int32 i; int32 i;
memset(g_Session, 0x00, (sizeof(SESSION) * MAXCONN) ); memset(g_Session, 0x00, (sizeof(SESSION) * MAXCONN) );
for(i = 0; i < MAXCONN; i++){ for(i = 0; i < MAXCONN; i++){
s = &g_Session[i]; s = &g_Session[i];
s->type = NST_FREE; s->type = NST_FREE;
s->disconnect_in_progress = false; s->disconnect_in_progress = false;
} }
// Initialize the corresponding event dispatcher // Initialize the corresponding event dispatcher
evdp_init(); evdp_init();
// //
add_timer_func_list(_network_async_free_netbuf_proc, "_network_async_free_netbuf_proc"); add_timer_func_list(_network_async_free_netbuf_proc, "_network_async_free_netbuf_proc");
}//end: network_init() }//end: network_init()
@ -66,7 +66,7 @@ void network_final(){
// @TODO: // @TODO:
// .. disconnect and cleanup everything! // .. disconnect and cleanup everything!
evdp_final(); evdp_final();
}//end: network_final() }//end: network_final()
@ -77,21 +77,21 @@ void network_do(){
register struct EVDP_EVENT *ev; register struct EVDP_EVENT *ev;
register int n, nfds; register int n, nfds;
register SESSION *s; register SESSION *s;
nfds = evdp_wait( l_events, EVENTS_PER_CYCLE, 1000); // @TODO: timer_getnext() nfds = evdp_wait( l_events, EVENTS_PER_CYCLE, 1000); // @TODO: timer_getnext()
for(n = 0; n < nfds; n++){ for(n = 0; n < nfds; n++){
ev = &l_events[n]; ev = &l_events[n];
s = &g_Session[ ev->fd ]; s = &g_Session[ ev->fd ];
if(ev->events & EVDP_EVENT_HUP){ if(ev->events & EVDP_EVENT_HUP){
network_disconnect( ev->fd ); network_disconnect( ev->fd );
continue; // no further event processing. continue; // no further event processing.
}// endif vent is HUP (disconnect) }// endif vent is HUP (disconnect)
if(ev->events & EVDP_EVENT_IN){ if(ev->events & EVDP_EVENT_IN){
if(s->onRecv != NULL){ if(s->onRecv != NULL){
if( false == s->onRecv(ev->fd) ){ if( false == s->onRecv(ev->fd) ){
network_disconnect(ev->fd); network_disconnect(ev->fd);
@ -101,11 +101,11 @@ void network_do(){
ShowError("network_do: fd #%u has no onRecv proc set. - disconnecting\n", ev->fd); ShowError("network_do: fd #%u has no onRecv proc set. - disconnecting\n", ev->fd);
network_disconnect(ev->fd); network_disconnect(ev->fd);
continue; continue;
} }
}// endif event is IN (recv) }// endif event is IN (recv)
if(ev->events & EVDP_EVENT_OUT){ if(ev->events & EVDP_EVENT_OUT){
if(s->onSend != NULL){ if(s->onSend != NULL){
if( false == s->onSend(ev->fd) ){ if( false == s->onSend(ev->fd) ){
@ -118,9 +118,9 @@ void network_do(){
continue; continue;
} }
}// endif event is OUT (send) }// endif event is OUT (send)
}//endfor }//endfor
}//end: network_do() }//end: network_do()
@ -135,7 +135,7 @@ static bool _setnonblock(int32 fd){
static bool _network_accept(int32 fd){ static bool _network_accept(int32 fd){
SESSION *listener = &g_Session[fd]; SESSION *listener = &g_Session[fd];
SESSION *s; SESSION *s;
union{ union{
struct sockaddr_in v4; struct sockaddr_in v4;
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
@ -156,7 +156,7 @@ static bool _network_accept(int32 fd){
}else{ }else{
#endif #endif
addrlen = sizeof(_addr.v4); addrlen = sizeof(_addr.v4);
addr = (struct sockaddr*)&_addr.v4; addr = (struct sockaddr*)&_addr.v4;
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
} }
#endif #endif
@ -170,9 +170,9 @@ static bool _network_accept(int32 fd){
if(newfd == -1){ if(newfd == -1){
if(errno == EAGAIN || errno == EWOULDBLOCK) if(errno == EAGAIN || errno == EWOULDBLOCK)
break; // this is fully valid & whished., se explaination on top of while(1) break; // this is fully valid & whished., se explaination on top of while(1)
// Otherwis .. we have serious problems :( seems tahat our listner has gone away.. // Otherwis .. we have serious problems :( seems tahat our listner has gone away..
// @TODO handle this .. // @TODO handle this ..
ShowError("_network_accept: accept() returned error. closing listener. (errno: %u / %s)\n", errno, strerror(errno)); ShowError("_network_accept: accept() returned error. closing listener. (errno: %u / %s)\n", errno, strerror(errno));
return false; // will call disconnect after return. return false; // will call disconnect after return.
@ -183,7 +183,7 @@ static bool _network_accept(int32 fd){
if(_setnonblock(newfd) == false){ if(_setnonblock(newfd) == false){
ShowError("_network_accept: failed to set newly accepted connection nonblocking (errno: %u / %s). - disconnecting.\n", errno, strerror(errno)); ShowError("_network_accept: failed to set newly accepted connection nonblocking (errno: %u / %s). - disconnecting.\n", errno, strerror(errno));
close(newfd); close(newfd);
continue; continue;
} }
#endif #endif
@ -198,31 +198,31 @@ static bool _network_accept(int32 fd){
// Create new Session. // Create new Session.
s = &g_Session[newfd]; s = &g_Session[newfd];
s->type = NST_CLIENT; s->type = NST_CLIENT;
// The new connection inherits listenr's handlers. // The new connection inherits listenr's handlers.
s->onDisconnect = listener->onDisconnect; s->onDisconnect = listener->onDisconnect;
s->onConnect = listener->onConnect; // maybe useless but .. fear the future .. :~ s->onConnect = listener->onConnect; // maybe useless but .. fear the future .. :~
// Register the new connection @ EVDP // Register the new connection @ EVDP
if( evdp_addclient(newfd, &s->evdp_data) == false){ if( evdp_addclient(newfd, &s->evdp_data) == false){
ShowError("_network_accept: failed to accept connection - event subsystem returned an error.\n"); ShowError("_network_accept: failed to accept connection - event subsystem returned an error.\n");
close(newfd); close(newfd);
s->type = NST_FREE; s->type = NST_FREE;
} }
// Call the onConnect handler on the listener. // Call the onConnect handler on the listener.
if( listener->onConnect(newfd) == false ){ if( listener->onConnect(newfd) == false ){
// Resfused by onConnect handler.. // Resfused by onConnect handler..
evdp_remove(newfd, &s->evdp_data); evdp_remove(newfd, &s->evdp_data);
close(newfd); close(newfd);
s->type = NST_FREE; s->type = NST_FREE;
s->data = NULL; // be on the safe side ~ ! s->data = NULL; // be on the safe side ~ !
continue; continue;
} }
} }
return true; return true;
@ -232,30 +232,30 @@ static bool _network_accept(int32 fd){
void network_disconnect(int32 fd){ void network_disconnect(int32 fd){
SESSION *s = &g_Session[fd]; SESSION *s = &g_Session[fd];
netbuf b, bn; netbuf b, bn;
// Prevent recursive calls // Prevent recursive calls
// by wrong implemented on disconnect handlers.. and such.. // by wrong implemented on disconnect handlers.. and such..
if(s->disconnect_in_progress == true) if(s->disconnect_in_progress == true)
return; return;
s->disconnect_in_progress = true; s->disconnect_in_progress = true;
// Disconnect Todo: // Disconnect Todo:
// - Call onDisconnect Handler // - Call onDisconnect Handler
// - Release all Assigned buffers. // - Release all Assigned buffers.
// - remove from event system (notifications) // - remove from event system (notifications)
// - cleanup session structure // - cleanup session structure
// - close connection. // - close connection.
// //
if(s->onDisconnect != NULL && if(s->onDisconnect != NULL &&
s->type != NST_LISTENER){ s->type != NST_LISTENER){
s->onDisconnect( fd ); s->onDisconnect( fd );
} }
// Read Buffer // Read Buffer
if(s->read.buf != NULL){ if(s->read.buf != NULL){
netbuffer_put(s->read.buf); netbuffer_put(s->read.buf);
s->read.buf = NULL; s->read.buf = NULL;
@ -267,30 +267,30 @@ void network_disconnect(int32 fd){
if(b == NULL) break; if(b == NULL) break;
bn = b->next; bn = b->next;
netbuffer_put(b); netbuffer_put(b);
b = bn; b = bn;
} }
s->write.buf = NULL; s->write.buf = NULL;
s->write.buf_last = NULL; s->write.buf_last = NULL;
s->write.n_outstanding = 0; s->write.n_outstanding = 0;
s->write.max_outstanding = 0; s->write.max_outstanding = 0;
// Remove from event system. // Remove from event system.
evdp_remove(fd, &s->evdp_data); evdp_remove(fd, &s->evdp_data);
// Cleanup Session Structure. // Cleanup Session Structure.
s->type = NST_FREE; s->type = NST_FREE;
s->data = NULL; // no application level data assigned s->data = NULL; // no application level data assigned
s->disconnect_in_progress = false; s->disconnect_in_progress = false;
// Close connection // Close connection
close(fd); close(fd);
}//end: network_disconnect() }//end: network_disconnect()
@ -320,7 +320,7 @@ int32 network_addlistener(bool v6, const char *addr, uint16 port){
ShowError("network_addlistener(%c, '%s', %u): socket() failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno)); ShowError("network_addlistener(%c, '%s', %u): socket() failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
return -1; return -1;
} }
// Too many connections? // Too many connections?
if(fd >= MAXCONN){ if(fd >= MAXCONN){
ShowError("network_addlistener(%c, '%s', %u): cannot create listener, exceeds more than supported connections (%u).\n", (v6==true?'t':'f'), addr, port, MAXCONN); ShowError("network_addlistener(%c, '%s', %u): cannot create listener, exceeds more than supported connections (%u).\n", (v6==true?'t':'f'), addr, port, MAXCONN);
@ -377,7 +377,7 @@ int32 network_addlistener(bool v6, const char *addr, uint16 port){
ShowError("network_addlistener(f, '%s', %u): bind failed (errno: %u / %s)\n", addr, port, errno, strerror(errno)); ShowError("network_addlistener(f, '%s', %u): bind failed (errno: %u / %s)\n", addr, port, errno, strerror(errno));
close(fd); close(fd);
return -1; return -1;
} }
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
} }
#endif #endif
@ -387,14 +387,14 @@ int32 network_addlistener(bool v6, const char *addr, uint16 port){
close(fd); close(fd);
return -1; return -1;
} }
// Set to nonblock! // Set to nonblock!
if(_setnonblock(fd) == false){ if(_setnonblock(fd) == false){
ShowError("network_addlistener(%c, '%s', %u): cannot set to nonblock (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno)); ShowError("network_addlistener(%c, '%s', %u): cannot set to nonblock (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
close(fd); close(fd);
return -1; return -1;
} }
// Rgister @ evdp. // Rgister @ evdp.
if( evdp_addlistener(fd, &s->evdp_data) != true){ if( evdp_addlistener(fd, &s->evdp_data) != true){
@ -406,7 +406,7 @@ int32 network_addlistener(bool v6, const char *addr, uint16 port){
// Apply flags on Session array for this conneciton. // Apply flags on Session array for this conneciton.
if(v6 == true) s->v6 = true; if(v6 == true) s->v6 = true;
else s->v6 = false; else s->v6 = false;
s->type = NST_LISTENER; s->type = NST_LISTENER;
s->onRecv = _network_accept; s->onRecv = _network_accept;
@ -420,16 +420,16 @@ static bool _network_connect_establishedHandler(int32 fd){
register SESSION *s = &g_Session[fd]; register SESSION *s = &g_Session[fd];
int val; int val;
socklen_t val_len; socklen_t val_len;
if(s->type == NST_FREE) if(s->type == NST_FREE)
return true; // due to multiple non coalesced event notifications return true; // due to multiple non coalesced event notifications
// this can happen .. when a previous handled event has already disconnected the connection // this can happen .. when a previous handled event has already disconnected the connection
// within the same cycle.. // within the same cycle..
val = -1; val = -1;
val_len = sizeof(val); val_len = sizeof(val);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &val, &val_len); getsockopt(fd, SOL_SOCKET, SO_ERROR, &val, &val_len);
if(val != 0){ if(val != 0){
// :( .. cleanup session.. // :( .. cleanup session..
s->type = NST_FREE; s->type = NST_FREE;
@ -439,37 +439,37 @@ static bool _network_connect_establishedHandler(int32 fd){
evdp_remove(fd, &s->evdp_data); evdp_remove(fd, &s->evdp_data);
close(fd); close(fd);
return true; // we CANT return false, return true; // we CANT return false,
// becuase the normal disconnect procedure would execute the ondisconnect handler, which we dont want .. in this case. // becuase the normal disconnect procedure would execute the ondisconnect handler, which we dont want .. in this case.
}else{ }else{
// ok // ok
if(s->onConnect(fd) == false) { if(s->onConnect(fd) == false) {
// onConnect handler has refused the connection .. // onConnect handler has refused the connection ..
// cleanup .. and ok // cleanup .. and ok
s->type = NST_FREE; s->type = NST_FREE;
s->onSend = NULL; s->onSend = NULL;
s->onConnect = NULL; s->onConnect = NULL;
s->onDisconnect = NULL; s->onDisconnect = NULL;
evdp_remove(fd, &s->evdp_data); evdp_remove(fd, &s->evdp_data);
close(fd); close(fd);
return true; // we dnot want the ondisconnect handler to be executed, so its okay to handle this by ourself. return true; // we dnot want the ondisconnect handler to be executed, so its okay to handle this by ourself.
} }
// connection established ! // connection established !
// //
if( evdp_outgoingconnection_established(fd, &s->evdp_data) == false ){ if( evdp_outgoingconnection_established(fd, &s->evdp_data) == false ){
return false; // we want the normal disconnect procedure.. with call to ondisconnect handler. return false; // we want the normal disconnect procedure.. with call to ondisconnect handler.
} }
s->onSend = NULL; s->onSend = NULL;
ShowStatus("#%u connection successfull!\n", fd); ShowStatus("#%u connection successfull!\n", fd);
} }
return true; return true;
}//end: _network_connect_establishedHandler() }//end: _network_connect_establishedHandler()
@ -515,7 +515,7 @@ int32 network_connect(bool v6,
// Originating IP/Port pair given ? // Originating IP/Port pair given ?
if(from_addr != NULL && *from_addr != 0){ if(from_addr != NULL && *from_addr != 0){
//.. //..
#ifdef SO_REUSEADDR #ifdef SO_REUSEADDR
optval=1; optval=1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
@ -526,7 +526,7 @@ int32 network_connect(bool v6,
memset(&ip6, 0x00, sizeof(ip6)); memset(&ip6, 0x00, sizeof(ip6));
ip6.sin6_family = AF_INET6; ip6.sin6_family = AF_INET6;
ip6.sin6_port = htons(from_port); ip6.sin6_port = htons(from_port);
if(inet_pton(AF_INET6, from_addr, &ip6.sin6_addr) != 1){ if(inet_pton(AF_INET6, from_addr, &ip6.sin6_addr) != 1){
ShowError("network_connect(t, '%s', %u...): cannot parse originating (from) IPV6 address (errno: %u / %s)\n", addr, port, errno, strerror(errno)); ShowError("network_connect(t, '%s', %u...): cannot parse originating (from) IPV6 address (errno: %u / %s)\n", addr, port, errno, strerror(errno));
close(fd); close(fd);
@ -545,7 +545,7 @@ int32 network_connect(bool v6,
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
} }
#endif #endif
} }
// Set non block // Set non block
@ -556,26 +556,26 @@ int32 network_connect(bool v6,
} }
// Create ip addr block to connect to .. // Create ip addr block to connect to ..
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
if(v6 == true){ if(v6 == true){
memset(&ip6, 0x00, sizeof(ip6)); memset(&ip6, 0x00, sizeof(ip6));
ip6.sin6_family = AF_INET6; ip6.sin6_family = AF_INET6;
ip6.sin6_port = htons(port); ip6.sin6_port = htons(port);
if(inet_pton(AF_INET6, addr, &ip6.sin6_addr) != 1){ if(inet_pton(AF_INET6, addr, &ip6.sin6_addr) != 1){
ShowError("network_connect(t, '%s', %u...): cannot parse destination IPV6 address (errno: %u / %s)\n", addr, port, errno, strerror(errno)); ShowError("network_connect(t, '%s', %u...): cannot parse destination IPV6 address (errno: %u / %s)\n", addr, port, errno, strerror(errno));
close(fd); close(fd);
return -1; return -1;
} }
}else{ }else{
#endif #endif
memset(&ip4, 0x00, sizeof(ip4)); memset(&ip4, 0x00, sizeof(ip4));
ip4.sin_family = AF_INET; ip4.sin_family = AF_INET;
ip4.sin_port = htons(port); ip4.sin_port = htons(port);
ip4.sin_addr.s_addr = inet_addr(addr); ip4.sin_addr.s_addr = inet_addr(addr);
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
} }
#endif #endif
@ -594,17 +594,17 @@ int32 network_connect(bool v6,
else else
#endif #endif
memcpy(&s->addr.v4, &ip4, sizeof(ip4)); memcpy(&s->addr.v4, &ip4, sizeof(ip4));
// Register @ EVDP. as outgoing (see doc of the function) // Register @ EVDP. as outgoing (see doc of the function)
if(evdp_addconnecting(fd, &s->evdp_data) == false){ if(evdp_addconnecting(fd, &s->evdp_data) == false){
ShowError("network_connect(%c, '%s', %u...): eventdispatcher subsystem returned an error.\n", (v6==true?'t':'f'), addr, port); ShowError("network_connect(%c, '%s', %u...): eventdispatcher subsystem returned an error.\n", (v6==true?'t':'f'), addr, port);
// cleanup session x.x.. // cleanup session x.x..
s->type = NST_FREE; s->type = NST_FREE;
s->onConnect = NULL; s->onConnect = NULL;
s->onDisconnect = NULL; s->onDisconnect = NULL;
s->onSend = NULL; s->onSend = NULL;
// close, return error code. // close, return error code.
close(fd); close(fd);
return -1; return -1;
@ -618,17 +618,17 @@ int32 network_connect(bool v6,
ret = connect(fd, (struct sockaddr*)&ip4, sizeof(ip4)); ret = connect(fd, (struct sockaddr*)&ip4, sizeof(ip4));
// //
if(ret != 0 && errno != EINPROGRESS){ if(ret != 0 && errno != EINPROGRESS){
ShowWarning("network_connect(%c, '%s', %u...): connection failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno)); ShowWarning("network_connect(%c, '%s', %u...): connection failed (errno: %u / %s)\n", (v6==true?'t':'f'), addr, port, errno, strerror(errno));
// Cleanup session .. // Cleanup session ..
s->type = NST_FREE; s->type = NST_FREE;
s->onConnect = NULL; s->onConnect = NULL;
s->onDisconnect = NULL; s->onDisconnect = NULL;
s->onSend = NULL; s->onSend = NULL;
// .. remove from evdp and close fd. // .. remove from evdp and close fd.
evdp_remove(fd, &s->evdp_data); evdp_remove(fd, &s->evdp_data);
close(fd); close(fd);
return -1; return -1;
@ -637,7 +637,7 @@ int32 network_connect(bool v6,
// ! The Info Message :~D // ! The Info Message :~D
ShowStatus("network_connect fd#%u (%s:%u) in progress.. \n", fd, addr, port); ShowStatus("network_connect fd#%u (%s:%u) in progress.. \n", fd, addr, port);
return fd; return fd;
}//end: network_connect() }//end: network_connect()
@ -648,20 +648,20 @@ static bool _onSend(int32 fd){
register int wLen; register int wLen;
if(s->type == NST_FREE) if(s->type == NST_FREE)
return true; // Possible due to multipl non coalsced event notifications return true; // Possible due to multipl non coalsced event notifications
// so onSend gets called after disconnect caused by an previous vent. // so onSend gets called after disconnect caused by an previous vent.
// we can ignore the call to onSend, then. // we can ignore the call to onSend, then.
buf = s->write.buf; buf = s->write.buf;
while(1){ while(1){
if(buf == NULL) if(buf == NULL)
break; break;
buf_next = buf->next; buf_next = buf->next;
szNeeded = (buf->dataLen - s->write.dataPos); // using th session-local .dataPos member, due to shared write buffer support. szNeeded = (buf->dataLen - s->write.dataPos); // using th session-local .dataPos member, due to shared write buffer support.
// try to write. // try to write.
wLen = write(fd, &buf->buf[s->write.dataPos], szNeeded); wLen = write(fd, &buf->buf[s->write.dataPos], szNeeded);
if(wLen == 0){ if(wLen == 0){
@ -669,16 +669,16 @@ static bool _onSend(int32 fd){
}else if(wLen == -1){ }else if(wLen == -1){
if(errno == EAGAIN || errno == EWOULDBLOCK) if(errno == EAGAIN || errno == EWOULDBLOCK)
return true; // dont disconnect / try again later. return true; // dont disconnect / try again later.
// all other errors. . // all other errors. .
return false; return false;
} }
// Wrote data.. => // Wrote data.. =>
szNeeded -= wLen; szNeeded -= wLen;
if(szNeeded > 0){ if(szNeeded > 0){
// still data left .. // still data left ..
// //
s->write.dataPos += wLen; // fix offset. s->write.dataPos += wLen; // fix offset.
return true; return true;
}else{ }else{
@ -686,29 +686,29 @@ static bool _onSend(int32 fd){
// could be returned to pool. // could be returned to pool.
netbuffer_put(buf); netbuffer_put(buf);
s->write.n_outstanding--; // When threadsafe -> Interlocked here. s->write.n_outstanding--; // When threadsafe -> Interlocked here.
s->write.dataPos = 0; s->write.dataPos = 0;
} }
buf = buf_next; buf = buf_next;
} }
// okay, // okay,
// reaching this part means: // reaching this part means:
// while interrupted by break - // while interrupted by break -
// which means all buffers are written, nothing left // which means all buffers are written, nothing left
// //
s->write.buf_last = NULL; s->write.buf_last = NULL;
s->write.buf = NULL; s->write.buf = NULL;
s->write.n_outstanding = 0; s->write.n_outstanding = 0;
s->write.dataPos = 0; s->write.dataPos = 0;
// Remove from event dispatcher (write notification) // Remove from event dispatcher (write notification)
// //
evdp_writable_remove(fd, &s->evdp_data); evdp_writable_remove(fd, &s->evdp_data);
return true; return true;
}//end: _onSend() }//end: _onSend()
@ -717,13 +717,13 @@ static bool _onRORecv(int32 fd){
register uint32 szNeeded; register uint32 szNeeded;
register char *p; register char *p;
register int rLen; register int rLen;
if(s->type == NST_FREE) if(s->type == NST_FREE)
return true; // Possible due to multiple non coalesced events by evdp. return true; // Possible due to multiple non coalesced events by evdp.
// simply ignore this call returning positive result. // simply ignore this call returning positive result.
// Initialize p and szNeeded depending on change // Initialize p and szNeeded depending on change
// //
switch(s->read.state){ switch(s->read.state){
case NRS_WAITOP: case NRS_WAITOP:
szNeeded = s->read.head_left; szNeeded = s->read.head_left;
@ -734,64 +734,64 @@ static bool _onRORecv(int32 fd){
szNeeded = s->read.head_left; szNeeded = s->read.head_left;
p = ((char*)&s->read.head[1]) + (2-szNeeded); p = ((char*)&s->read.head[1]) + (2-szNeeded);
break; break;
case NRS_WAITDATA:{ case NRS_WAITDATA:{
register netbuf buf = s->read.buf; register netbuf buf = s->read.buf;
szNeeded = (buf->dataLen - buf->dataPos); szNeeded = (buf->dataLen - buf->dataPos);
p = (char*)&buf->buf[ buf->dataPos ]; p = (char*)&buf->buf[ buf->dataPos ];
} }
break; break;
default: default:
// .. the impossible gets possible .. // .. the impossible gets possible ..
ShowError("_onRORecv: fd #%u has unknown read.state (%d) - disconnecting\n", fd, s->read.state); ShowError("_onRORecv: fd #%u has unknown read.state (%d) - disconnecting\n", fd, s->read.state);
return false; return false;
break; break;
} }
// //
rLen = read(fd, p, szNeeded); rLen = read(fd, p, szNeeded);
if(rLen == 0){ if(rLen == 0){
// eof.. // eof..
return false; return false;
}else if(rLen == -1){ }else if(rLen == -1){
if(errno == EAGAIN || errno == EWOULDBLOCK){ if(errno == EAGAIN || errno == EWOULDBLOCK){
// try again later .. (this case shouldnt happen, because we're event trigered.. but .. sometimes it happens :) // try again later .. (this case shouldnt happen, because we're event trigered.. but .. sometimes it happens :)
return true; return true;
} }
// an additional interesting case would be // an additional interesting case would be
// EINTR, this 'could' be handled .. but: // EINTR, this 'could' be handled .. but:
// posix says that its possible that data gets currupted during irq // posix says that its possible that data gets currupted during irq
// or data gor read and not reported.., so we'd have a data loss.. // or data gor read and not reported.., so we'd have a data loss..
// (which shouldnt happen with stream based protocols such as tcp) // (which shouldnt happen with stream based protocols such as tcp)
// its better to disonnect the client in that case. // its better to disonnect the client in that case.
return false; return false;
} }
// //
// Got Data: // Got Data:
// next action also depends on current state .. // next action also depends on current state ..
// //
szNeeded -= rLen; szNeeded -= rLen;
switch(s->read.state){ switch(s->read.state){
case NRS_WAITOP: case NRS_WAITOP:
if(szNeeded > 0){ if(szNeeded > 0){
// still data missing .. // still data missing ..
s->read.head_left = szNeeded; s->read.head_left = szNeeded;
return true; // wait for completion. return true; // wait for completion.
}else{ }else{
// complete .. // complete ..
// next state depends on packet type. // next state depends on packet type.
s->read.head[1] = ((uint16*)s->netparser_data)[ s->read.head[0] ]; // store lenght of packet by opcode head[0] to head[1] s->read.head[1] = ((uint16*)s->netparser_data)[ s->read.head[0] ]; // store lenght of packet by opcode head[0] to head[1]
if(s->read.head[1] == ROPACKET_UNKNOWN){ if(s->read.head[1] == ROPACKET_UNKNOWN){
// unknown packet - disconnect // unknown packet - disconnect
ShowWarning("_onRORecv: fd #%u got unlnown packet 0x%04x - disconnecting.\n", fd, s->read.head[0]); ShowWarning("_onRORecv: fd #%u got unlnown packet 0x%04x - disconnecting.\n", fd, s->read.head[0]);
@ -804,74 +804,74 @@ static bool _onRORecv(int32 fd){
s->read.head_left = 2; s->read.head_left = 2;
return true; // return true; //
} }
else if(s->read.head[1] == 2){ else if(s->read.head[1] == 2){
// packet has no data (only opcode) // packet has no data (only opcode)
register netbuf buf = netbuffer_get(2); // :D whoohoo its giant! register netbuf buf = netbuffer_get(2); // :D whoohoo its giant!
NBUFW(buf, 0) = s->read.head[0]; // store opcode @ packet begin. NBUFW(buf, 0) = s->read.head[0]; // store opcode @ packet begin.
buf->dataPos = 2; buf->dataPos = 2;
buf->dataLen = 2; buf->dataLen = 2;
buf->next = NULL; buf->next = NULL;
// Back to initial state -> Need opcode. // Back to initial state -> Need opcode.
s->read.state = NRS_WAITOP; s->read.state = NRS_WAITOP;
s->read.head_left = 2; s->read.head_left = 2;
s->read.buf = NULL; s->read.buf = NULL;
// Call completion routine here. // Call completion routine here.
s->onPacketComplete(fd, s->read.head[0], 2, buf); s->onPacketComplete(fd, s->read.head[0], 2, buf);
return true; // done :) return true; // done :)
} }
else{ else{
// paket needs .. data .. // paket needs .. data ..
register netbuf buf = netbuffer_get( s->read.head[1] ); register netbuf buf = netbuffer_get( s->read.head[1] );
NBUFW(buf, 0) = s->read.head[0]; // store opcode @ packet begin. NBUFW(buf, 0) = s->read.head[0]; // store opcode @ packet begin.
buf->dataPos = 2; buf->dataPos = 2;
buf->dataLen = s->read.head[1]; buf->dataLen = s->read.head[1];
buf->next = NULL; buf->next = NULL;
// attach buffer. // attach buffer.
s->read.buf = buf; s->read.buf = buf;
// set state: // set state:
s->read.state = NRS_WAITDATA; s->read.state = NRS_WAITDATA;
return true; return true;
} }
}//endif: szNeeded > 0 (opcode read completed?) }//endif: szNeeded > 0 (opcode read completed?)
break; break;
case NRS_WAITLEN: case NRS_WAITLEN:
if(szNeeded > 0){ if(szNeeded > 0){
// incomplete .. // incomplete ..
s->read.head_left = szNeeded; s->read.head_left = szNeeded;
return true; return true;
}else{ }else{
if(s->read.head[1] == 4){ if(s->read.head[1] == 4){
// packet has no data (only opcode + length) // packet has no data (only opcode + length)
register netbuf buf = netbuffer_get( 4 ); register netbuf buf = netbuffer_get( 4 );
NBUFL(buf, 0) = *((uint32*)&s->read.head[0]); // copy Opcode + length to netbuffer using MOVL NBUFL(buf, 0) = *((uint32*)&s->read.head[0]); // copy Opcode + length to netbuffer using MOVL
buf->dataPos = 4; buf->dataPos = 4;
buf->dataLen = 4; buf->dataLen = 4;
buf->next = NULL; buf->next = NULL;
// set initial state (need opcode) // set initial state (need opcode)
s->read.state = NRS_WAITOP; s->read.state = NRS_WAITOP;
s->read.head_left = 2; s->read.head_left = 2;
s->read.buf = NULL; s->read.buf = NULL;
// call completion routine. // call completion routine.
s->onPacketComplete(fd, s->read.head[0], 4, buf); s->onPacketComplete(fd, s->read.head[0], 4, buf);
return true; return true;
} }
else if(s->read.head[1] < 4){ else if(s->read.head[1] < 4){
// invalid header. // invalid header.
@ -882,64 +882,64 @@ static bool _onRORecv(int32 fd){
// Data needed // Data needed
// next state -> waitdata! // next state -> waitdata!
register netbuf buf = netbuffer_get( s->read.head[1] ); register netbuf buf = netbuffer_get( s->read.head[1] );
NBUFL(buf, 0) = *((uint32*)&s->read.head[0]); // copy Opcode + length to netbuffer using MOVL NBUFL(buf, 0) = *((uint32*)&s->read.head[0]); // copy Opcode + length to netbuffer using MOVL
buf->dataPos = 4; buf->dataPos = 4;
buf->dataLen = s->read.head[1]; buf->dataLen = s->read.head[1];
buf->next = NULL; buf->next = NULL;
// attach to session: // attach to session:
s->read.buf = buf; s->read.buf = buf;
s->read.state = NRS_WAITDATA; s->read.state = NRS_WAITDATA;
return true; return true;
} }
}//endif: szNeeded > 0 (length read complete?) }//endif: szNeeded > 0 (length read complete?)
break; break;
case NRS_WAITDATA: case NRS_WAITDATA:
if(szNeeded == 0){ if(szNeeded == 0){
// Packet finished! // Packet finished!
// compltion. // compltion.
register netbuf buf = s->read.buf; register netbuf buf = s->read.buf;
// set initial state. // set initial state.
s->read.state = NRS_WAITOP; s->read.state = NRS_WAITOP;
s->read.head_left = 2; s->read.head_left = 2;
s->read.buf = NULL; s->read.buf = NULL;
// Call completion routine. // Call completion routine.
s->onPacketComplete(fd, NBUFW(buf, 0), buf->dataLen, buf); s->onPacketComplete(fd, NBUFW(buf, 0), buf->dataLen, buf);
return true; return true;
}else{ }else{
// still data needed // still data needed
s->read.buf->dataPos += rLen; s->read.buf->dataPos += rLen;
return true; return true;
} }
break; break;
// //
default: default:
ShowError("_onRORecv: fd #%u has unknown read.state (%d) [2] - disconnecting\n", fd, s->read.state); ShowError("_onRORecv: fd #%u has unknown read.state (%d) [2] - disconnecting\n", fd, s->read.state);
return false; return false;
break; break;
} }
return false; return false;
}//end: _onRORecv() }//end: _onRORecv()
void network_send(int32 fd, netbuf buf){ void network_send(int32 fd, netbuf buf){
register SESSION *s = &g_Session[fd]; register SESSION *s = &g_Session[fd];
#ifdef PARANOID_CHECKS #ifdef PARANOID_CHECKS
if(fd >= MAXCONN){ if(fd >= MAXCONN){
ShowError("network_send: tried to attach buffer to connection idientifer #%u which is out of bounds.\n", fd); ShowError("network_send: tried to attach buffer to connection idientifer #%u which is out of bounds.\n", fd);
@ -951,84 +951,84 @@ void network_send(int32 fd, netbuf buf){
if(s->type == NST_FREE) if(s->type == NST_FREE)
return; return;
// Check Max Outstanding buffers limit. // Check Max Outstanding buffers limit.
if( (s->write.max_outstanding > 0) && if( (s->write.max_outstanding > 0) &&
(s->write.n_outstanding >= s->write.max_outstanding) ){ (s->write.n_outstanding >= s->write.max_outstanding) ){
ShowWarning("network_send: fd #%u max Outstanding buffers exceeded. - disconnecting.\n", fd); ShowWarning("network_send: fd #%u max Outstanding buffers exceeded. - disconnecting.\n", fd);
network_disconnect(fd); network_disconnect(fd);
// //
_network_free_netbuf_async(buf); _network_free_netbuf_async(buf);
return; return;
} }
// Attach to the end: // Attach to the end:
buf->next = NULL; buf->next = NULL;
if(s->write.buf_last != NULL){ if(s->write.buf_last != NULL){
s->write.buf_last->next = buf; s->write.buf_last->next = buf;
s->write.buf_last = buf; s->write.buf_last = buf;
}else{ }else{
// currently no buffer attached. // currently no buffer attached.
s->write.buf = s->write.buf_last = buf; s->write.buf = s->write.buf_last = buf;
// register @ evdp for writable notification. // register @ evdp for writable notification.
evdp_writable_add(fd, &s->evdp_data); // evdp_writable_add(fd, &s->evdp_data); //
} }
// //
s->write.n_outstanding++; s->write.n_outstanding++;
}//end: network_send() }//end: network_send()
void network_parser_set_ro(int32 fd, void network_parser_set_ro(int32 fd,
int16 *packetlentable, int16 *packetlentable,
void (*onPacketCompleteProc)(int32 fd, uint16 op, uint16 len, netbuf buf) void (*onPacketCompleteProc)(int32 fd, uint16 op, uint16 len, netbuf buf)
){ ){
register SESSION *s = &g_Session[fd]; register SESSION *s = &g_Session[fd];
register netbuf b, nb; // used for potential free attached buffers. register netbuf b, nb; // used for potential free attached buffers.
if(s->type == NST_FREE) if(s->type == NST_FREE)
return; return;
s->onPacketComplete = onPacketCompleteProc; s->onPacketComplete = onPacketCompleteProc;
s->onRecv = _onRORecv; // .. s->onRecv = _onRORecv; // ..
s->onSend = _onSend; // Using the normal generic netbuf based send function. s->onSend = _onSend; // Using the normal generic netbuf based send function.
s->netparser_data = packetlentable; s->netparser_data = packetlentable;
// Initial State -> Need Packet OPCode. // Initial State -> Need Packet OPCode.
s->read.state = NRS_WAITOP; s->read.state = NRS_WAITOP;
s->read.head_left = 2; s->read.head_left = 2;
// Detach (if..) all buffers. // Detach (if..) all buffers.
if(s->read.buf != NULL){ if(s->read.buf != NULL){
_network_free_netbuf_async(s->read.buf); // _network_free_netbuf_async(s->read.buf); //
s->read.buf = NULL; s->read.buf = NULL;
} }
if(s->write.buf != NULL){ if(s->write.buf != NULL){
b = s->write.buf; b = s->write.buf;
while(1){ while(1){
nb = b->next; nb = b->next;
_network_free_netbuf_async(b); _network_free_netbuf_async(b);
b = nb; b = nb;
} }
s->write.buf = NULL; s->write.buf = NULL;
s->write.buf_last = NULL; s->write.buf_last = NULL;
s->write.n_outstanding = 0; s->write.n_outstanding = 0;
} }
// not changing any limits on outstanding .. // not changing any limits on outstanding ..
// //
}//end: network_parser_set_ro() }//end: network_parser_set_ro()

View File

@ -3,7 +3,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include "cbasetypes.h" #include "cbasetypes.h"
#include "netbuffer.h" #include "netbuffer.h"
#include "evdp.h" #include "evdp.h"
#ifndef MAXCONN #ifndef MAXCONN
@ -14,19 +14,19 @@
typedef struct SESSION{ typedef struct SESSION{
EVDP_DATA evdp_data; // Must be always the frist member! (some evdp's may rely on this fact) EVDP_DATA evdp_data; // Must be always the frist member! (some evdp's may rely on this fact)
// Connection Type // Connection Type
enum{ NST_FREE=0, NST_LISTENER = 1, NST_CLIENT=2, NST_OUTGOING=3} type; enum{ NST_FREE=0, NST_LISTENER = 1, NST_CLIENT=2, NST_OUTGOING=3} type;
// Flags / Settings. // Flags / Settings.
bool v6; // is v6? bool v6; // is v6?
bool disconnect_in_progress; // To prevent stack overflows / recursive calls. bool disconnect_in_progress; // To prevent stack overflows / recursive calls.
union{ // union to save memory. union{ // union to save memory.
struct sockaddr_in v4; struct sockaddr_in v4;
struct sockaddr_in6 v6; struct sockaddr_in6 v6;
}addr; }addr;
// "lowlevel" Handlers // "lowlevel" Handlers
// (Implemented by the protocol specific parser) // (Implemented by the protocol specific parser)
@ -34,9 +34,9 @@ typedef struct SESSION{
bool (*onRecv)(int32 fd); // return false = disconnect bool (*onRecv)(int32 fd); // return false = disconnect
bool (*onSend)(int32 fd); // return false = disconnect bool (*onSend)(int32 fd); // return false = disconnect
// Event Handlers for LISTENER type sockets // Event Handlers for LISTENER type sockets
// //
// onConnect gets Called when a connection has been // onConnect gets Called when a connection has been
// successfully accepted. // successfully accepted.
// Session entry is available in this Handler! // Session entry is available in this Handler!
// A returncode of false will reejct the connection (disconnect) // A returncode of false will reejct the connection (disconnect)
@ -44,46 +44,46 @@ typedef struct SESSION{
// The onDisconnect handler wont get called! // The onDisconnect handler wont get called!
// Note: the onConnect Handler is also responsible for setting // Note: the onConnect Handler is also responsible for setting
// the appropriate netparser (which implements onRecv/onSend..) [protocol specific] // the appropriate netparser (which implements onRecv/onSend..) [protocol specific]
// //
// onDisconnect gets called when a connection gets disconnected // onDisconnect gets called when a connection gets disconnected
// (by peer as well as by core) // (by peer as well as by core)
// //
bool (*onConnect)(int32 fd); // return false = disconnect (wont accept) bool (*onConnect)(int32 fd); // return false = disconnect (wont accept)
void (*onDisconnect)(int32 fd); void (*onDisconnect)(int32 fd);
// //
// Parser specific data // Parser specific data
// //
void *netparser_data; // incase of RO Packet Parser, pointer to packet len table (uint16array) void *netparser_data; // incase of RO Packet Parser, pointer to packet len table (uint16array)
void (*onPacketComplete)(int32 fd, uint16 op, uint16 len, netbuf buf); void (*onPacketComplete)(int32 fd, uint16 op, uint16 len, netbuf buf);
// //
// Buffers // Buffers
// //
struct{ struct{
enum NETREADSTATE { NRS_WAITOP = 0, NRS_WAITLEN = 1, NRS_WAITDATA = 2} state; enum NETREADSTATE { NRS_WAITOP = 0, NRS_WAITLEN = 1, NRS_WAITDATA = 2} state;
uint32 head_left; uint32 head_left;
uint16 head[2]; uint16 head[2];
netbuf buf; netbuf buf;
} read; } read;
struct{ struct{
uint32 max_outstanding; uint32 max_outstanding;
uint32 n_outstanding; uint32 n_outstanding;
uint32 dataPos; uint32 dataPos;
netbuf buf, buf_last; netbuf buf, buf_last;
} write; } write;
// Application Level data Pointer // Application Level data Pointer
// (required for backward compatibility with previous athena socket system.) // (required for backward compatibility with previous athena socket system.)
void *data; void *data;
} SESSION; } SESSION;
@ -101,10 +101,10 @@ void network_final();
void network_do(); void network_do();
/** /**
* Adds a new listner. * Adds a new listner.
* *
* @param v6 v6 listner? * @param v6 v6 listner?
* @param *addr the address to listen on. * @param *addr the address to listen on.
* @param port port to listen on * @param port port to listen on
* *
@ -135,7 +135,7 @@ int32 network_connect(bool v6,
void (*onConnectionLooseHandler)(int32 fd) void (*onConnectionLooseHandler)(int32 fd)
); );
/** /**
* Disconnects the given connection * Disconnects the given connection
@ -143,14 +143,14 @@ int32 network_connect(bool v6,
* @param fd connection identifier. * @param fd connection identifier.
* *
* @Note: * @Note:
* - onDisconnect callback gets called! * - onDisconnect callback gets called!
* - cleares (returns) all assigned buffers * - cleares (returns) all assigned buffers
* *
*/ */
void network_disconnect(int32 fd); void network_disconnect(int32 fd);
/** /**
* Attach's a netbuffer at the end of sending queue to the given connection * Attach's a netbuffer at the end of sending queue to the given connection
* *
* @param fd connection identifier * @param fd connection identifier
@ -161,7 +161,7 @@ void network_send(int32 fd, netbuf buf);
/** /**
* Sets the parser to RO Protocol like Packet Parser. * Sets the parser to RO Protocol like Packet Parser.
* *
* @param fd connection identifier * @param fd connection identifier
* @param *packetlentable pointer to array of uint16 in size of UINT16_MAX, * @param *packetlentable pointer to array of uint16 in size of UINT16_MAX,
* @param onComplteProc callback for packet completion. * @param onComplteProc callback for packet completion.
@ -178,7 +178,7 @@ void network_send(int32 fd, netbuf buf);
*/ */
void network_parser_set_ro(int32 fd, void network_parser_set_ro(int32 fd,
int16 *packetlentable, int16 *packetlentable,
void (*onPacketCompleteProc)(int32 fd, uint16 op, uint16 len, netbuf buf) void (*onPacketCompleteProc)(int32 fd, uint16 op, uint16 len, netbuf buf)
); );
#define ROPACKET_UNKNOWN UINT16_MAX #define ROPACKET_UNKNOWN UINT16_MAX
#define ROPACKET_DYNLEN 0 #define ROPACKET_DYNLEN 0

View File

@ -17,10 +17,10 @@ int nullpo_chk_f(const char *file, int line, const char *func, const void *targe
const char *fmt, ...) const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (target != NULL) if (target != NULL)
return 0; return 0;
va_start(ap, fmt); va_start(ap, fmt);
nullpo_info_core(file, line, func, fmt, ap); nullpo_info_core(file, line, func, fmt, ap);
va_end(ap); va_end(ap);
@ -39,11 +39,11 @@ int nullpo_chk(const char *file, int line, const char *func, const void *target)
/*====================================== /*======================================
* nullpo Information output (external call) * nullpo Information output (external call)
*--------------------------------------*/ *--------------------------------------*/
void nullpo_info_f(const char *file, int line, const char *func, void nullpo_info_f(const char *file, int line, const char *func,
const char *fmt, ...) const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
nullpo_info_core(file, line, func, fmt, ap); nullpo_info_core(file, line, func, fmt, ap);
va_end(ap); va_end(ap);
@ -57,12 +57,12 @@ void nullpo_info(const char *file, int line, const char *func)
static void nullpo_info_core_(const char *file, int line, const char *func){ static void nullpo_info_core_(const char *file, int line, const char *func){
if (file == NULL) if (file == NULL)
file = "??"; file = "??";
func = func =
func == NULL ? "unknown": func == NULL ? "unknown":
func[0] == '\0' ? "unknown": func[0] == '\0' ? "unknown":
func; func;
ShowMessage("--- nullpo info --------------------------------------------\n"); ShowMessage("--- nullpo info --------------------------------------------\n");
ShowMessage("%s:%d: in func `%s'\n", file, line, func); ShowMessage("%s:%d: in func `%s'\n", file, line, func);
} }
@ -70,7 +70,7 @@ static void nullpo_info_core_(const char *file, int line, const char *func){
/*====================================== /*======================================
* nullpo intelligence Output (Main) * nullpo intelligence Output (Main)
*--------------------------------------*/ *--------------------------------------*/
static void nullpo_info_core(const char *file, int line, const char *func, static void nullpo_info_core(const char *file, int line, const char *func,
const char *fmt, va_list ap) const char *fmt, va_list ap)
{ {
nullpo_info_core_(file,line,func); nullpo_info_core_(file,line,func);
@ -79,7 +79,7 @@ static void nullpo_info_core(const char *file, int line, const char *func,
if (fmt[0] != '\0') if (fmt[0] != '\0')
{ {
vprintf(fmt, ap); vprintf(fmt, ap);
// Check whether the new line at the end // Check whether the new line at the end
if (fmt[strlen(fmt)-1] != '\n') if (fmt[strlen(fmt)-1] != '\n')
ShowMessage("\n"); ShowMessage("\n");

View File

@ -217,7 +217,7 @@ void nullpo_info(const char *file, int line, const char *func);
* *
*-------------------------------------- *--------------------------------------
*/ */
void nullpo_info_f(const char *file, int line, const char *func, void nullpo_info_f(const char *file, int line, const char *func,
const char *fmt, ...) const char *fmt, ...)
__attribute__((format(printf,4,5))); __attribute__((format(printf,4,5)));

View File

@ -1,7 +1,7 @@
// //
// Athena style config parser // Athena style config parser
// (would be better to have "one" implementation instead of .. 4 :) // (would be better to have "one" implementation instead of .. 4 :)
// //
// //
// Author: Florian Wilkemeyer <fw@f-ws.de> // Author: Florian Wilkemeyer <fw@f-ws.de>
// //
@ -33,7 +33,7 @@ struct conf_value{
int64 intval; int64 intval;
bool bval; bool bval;
double floatval; double floatval;
size_t strval_len; // not includung \0 size_t strval_len; // not includung \0
char strval[16]; char strval[16];
}; };
@ -42,22 +42,22 @@ struct conf_value{
static struct conf_value *makeValue(const char *key, char *val, size_t val_len){ static struct conf_value *makeValue(const char *key, char *val, size_t val_len){
struct conf_value *v; struct conf_value *v;
/* size_t sz; /* size_t sz;
sz = sizeof(struct conf_value); sz = sizeof(struct conf_value);
if(val_len >= sizeof(v->strval)) if(val_len >= sizeof(v->strval))
sz += (val_len - sizeof(v->strval) + 1);*/ sz += (val_len - sizeof(v->strval) + 1);*/
v = (struct conf_value*)aCalloc(1, sizeof(struct conf_value)); v = (struct conf_value*)aCalloc(1, sizeof(struct conf_value));
if(v == NULL){ if(v == NULL){
ShowFatalError("raconf: makeValue => Out of Memory while allocating new node.\n"); ShowFatalError("raconf: makeValue => Out of Memory while allocating new node.\n");
return NULL; return NULL;
} }
memcpy(v->strval, val, val_len); memcpy(v->strval, val, val_len);
v->strval[val_len+1] = '\0'; v->strval[val_len+1] = '\0';
v->strval_len = val_len; v->strval_len = val_len;
// Parse boolean value: // Parse boolean value:
if((val_len == 4) && (strncmpi("true", val, 4) == 0)) if((val_len == 4) && (strncmpi("true", val, 4) == 0))
v->bval = true; v->bval = true;
@ -80,13 +80,13 @@ static struct conf_value *makeValue(const char *key, char *val, size_t val_len){
else if((val_len == 4) && (strncmpi("nein", val, 4) == 0)) else if((val_len == 4) && (strncmpi("nein", val, 4) == 0))
v->bval = false; v->bval = false;
else if((val_len == 1) && (*val == '0')) else if((val_len == 1) && (*val == '0'))
v->bval = false; v->bval = false;
else else
v->bval = false; // assume false. v->bval = false; // assume false.
// Parse number // Parse number
// Supported formats: // Supported formats:
// prefix: 0x hex . // prefix: 0x hex .
// postix: h for hex // postix: h for hex
// b for bin (dual) // b for bin (dual)
if( (val_len >= 1 && (val[val_len] == 'h')) || (val_len >= 2 && (val[0] == '0' && val[1] == 'x')) ){//HEX! if( (val_len >= 1 && (val[val_len] == 'h')) || (val_len >= 2 && (val[0] == '0' && val[1] == 'x')) ){//HEX!
@ -104,7 +104,7 @@ static struct conf_value *makeValue(const char *key, char *val, size_t val_len){
// is it float? // is it float?
bool is_float = false; bool is_float = false;
char *p; char *p;
for(p = val; *p != '\0'; p++){ for(p = val; *p != '\0'; p++){
if(*p == '.'){ if(*p == '.'){
v->floatval = strtod(val, NULL); v->floatval = strtod(val, NULL);
@ -113,7 +113,7 @@ static struct conf_value *makeValue(const char *key, char *val, size_t val_len){
break; break;
} }
} }
if(is_float == false){ if(is_float == false){
v->intval = strtoull(val, NULL, 10); v->intval = strtoull(val, NULL, 10);
v->floatval = (double) v->intval; v->floatval = (double) v->intval;
@ -125,8 +125,8 @@ static struct conf_value *makeValue(const char *key, char *val, size_t val_len){
else else
v->intval = 0; v->intval = 0;
} }
return v; return v;
}//end: makeValue() }//end: makeValue()
@ -139,38 +139,38 @@ static bool configParse(raconf inst, const char *fileName){
int linecnt; int linecnt;
size_t linelen; size_t linelen;
size_t currentSection_len; size_t currentSection_len;
fp = fopen(fileName, "r"); fp = fopen(fileName, "r");
if(fp == NULL){ if(fp == NULL){
ShowError("configParse: cannot open '%s' for reading.\n", fileName); ShowError("configParse: cannot open '%s' for reading.\n", fileName);
return false; return false;
} }
// Start with empty section: // Start with empty section:
currentSection[0] = '\0'; currentSection[0] = '\0';
currentSection_len = 0; currentSection_len = 0;
// //
linecnt = 0; linecnt = 0;
while(1){ while(1){
linecnt++; linecnt++;
if(fgets(line, sizeof(line), fp) != line) if(fgets(line, sizeof(line), fp) != line)
break; break;
linelen = strlen(line); linelen = strlen(line);
p = line; p = line;
// Skip whitespaces from beginning (space and tab) // Skip whitespaces from beginning (space and tab)
_line_begin_skip_whities: _line_begin_skip_whities:
c = *p; c = *p;
if(c == ' ' || c == '\t'){ if(c == ' ' || c == '\t'){
p++; p++;
linelen--; linelen--;
goto _line_begin_skip_whities; goto _line_begin_skip_whities;
} }
// Remove linebreaks as (cr or lf) and whitespaces from line end! // Remove linebreaks as (cr or lf) and whitespaces from line end!
_line_end_skip_whities_and_breaks: _line_end_skip_whities_and_breaks:
c = p[linelen-1]; c = p[linelen-1];
@ -178,29 +178,29 @@ static bool configParse(raconf inst, const char *fileName){
p[--linelen] = '\0'; p[--linelen] = '\0';
goto _line_end_skip_whities_and_breaks; goto _line_end_skip_whities_and_breaks;
} }
// Empty line? // Empty line?
// or line starts with comment (commented out)? // or line starts with comment (commented out)?
if(linelen == 0 || (p[0] == '/' && p[1] == '/') || p[0] == ';') if(linelen == 0 || (p[0] == '/' && p[1] == '/') || p[0] == ';')
continue; continue;
// Variable names can contain: // Variable names can contain:
// A-Za-z-_.0-9 // A-Za-z-_.0-9
// //
// Sections start with [ .. ] (INI Style) // Sections start with [ .. ] (INI Style)
// //
c = *p; c = *p;
// check what we have.. :) // check what we have.. :)
if(c == '['){ // got section! if(c == '['){ // got section!
// Got Section! // Got Section!
// Search for ] // Search for ]
char *start = (p+1); char *start = (p+1);
while(1){ while(1){
++p; ++p;
c = *p; c = *p;
if(c == '\0'){ if(c == '\0'){
ShowError("Syntax Error: unterminated Section name in %s:%u (expected ']')\n", fileName, linecnt); ShowError("Syntax Error: unterminated Section name in %s:%u (expected ']')\n", fileName, linecnt);
fclose(fp); fclose(fp);
@ -211,14 +211,14 @@ static bool configParse(raconf inst, const char *fileName){
fclose(fp); fclose(fp);
return false; return false;
} }
// Set section! // Set section!
*p = '\0'; // add termination here. *p = '\0'; // add termination here.
memcpy(currentSection, start, (p-start)+1 ); // we'll copy \0, too! (we replaced the ] backet with \0.) memcpy(currentSection, start, (p-start)+1 ); // we'll copy \0, too! (we replaced the ] backet with \0.)
currentSection_len = (p-start); currentSection_len = (p-start);
break; break;
}else if( (c >= '0' && c <= '9') || (c == '-') || (c == ' ') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){ }else if( (c >= '0' && c <= '9') || (c == '-') || (c == ' ') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){
// skip .. (allowed char / specifier) // skip .. (allowed char / specifier)
continue; continue;
@ -227,43 +227,43 @@ static bool configParse(raconf inst, const char *fileName){
fclose(fp); fclose(fp);
return false; return false;
} }
}//endwhile: parse section name }//endwhile: parse section name
}else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){ }else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){
// Got variable! // Got variable!
// Search for '=' or ':' wich termiantes the name // Search for '=' or ':' wich termiantes the name
char *start = p; char *start = p;
char *valuestart = NULL; char *valuestart = NULL;
size_t start_len; size_t start_len;
while(1){ while(1){
++p; ++p;
c = *p; c = *p;
if(c == '\0'){ if(c == '\0'){
ShowError("Syntax Error: unterminated Variable name in %s:%u\n", fileName, linecnt); ShowError("Syntax Error: unterminated Variable name in %s:%u\n", fileName, linecnt);
fclose(fp); fclose(fp);
return false; return false;
}else if( (c == '=') || (c == ':') ){ }else if( (c == '=') || (c == ':') ){
// got name termination // got name termination
*p = '\0'; // Terminate it so (start) will hold the pointer to the name. *p = '\0'; // Terminate it so (start) will hold the pointer to the name.
break; break;
}else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){ }else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){
// skip .. allowed char // skip .. allowed char
continue; continue;
}else{ }else{
ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Variable name.\n", c, fileName, linecnt, (p-line)); ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Variable name.\n", c, fileName, linecnt, (p-line));
fclose(fp); fclose(fp);
return false; return false;
} }
}//endwhile: parse var name }//endwhile: parse var name
start_len = (p-start); start_len = (p-start);
if(start_len >= VARNAME_LEN){ if(start_len >= VARNAME_LEN){
ShowError("%s:%u Variable length exceeds limit of %u Characters.\n", fileName, linecnt, VARNAME_LEN-1); ShowError("%s:%u Variable length exceeds limit of %u Characters.\n", fileName, linecnt, VARNAME_LEN-1);
@ -274,20 +274,20 @@ static bool configParse(raconf inst, const char *fileName){
fclose(fp); fclose(fp);
return false; return false;
} }
valuestart = (p+1); valuestart = (p+1);
// Skip whitespace from begin of value (tab and space) // Skip whitespace from begin of value (tab and space)
_skip_value_begin_whities: _skip_value_begin_whities:
c = *valuestart; c = *valuestart;
if(c == ' ' || c == '\t'){ if(c == ' ' || c == '\t'){
valuestart++; valuestart++;
goto _skip_value_begin_whities; goto _skip_value_begin_whities;
} }
// Scan for value termination, // Scan for value termination,
// wich can be \0 or comment start (// or ; (INI) ) // wich can be \0 or comment start (// or ; (INI) )
// //
p = valuestart; p = valuestart;
@ -305,15 +305,15 @@ static bool configParse(raconf inst, const char *fileName){
*p = '\0'; *p = '\0';
break; break;
} }
p++; p++;
}//endwhile: search var value end. }//endwhile: search var value end.
// Strip whitespaces from end of value. // Strip whitespaces from end of value.
if(valuestart != p){ // not empty! if(valuestart != p){ // not empty!
p--; p--;
_strip_value_end_whities: _strip_value_end_whities:
c = *p; c = *p;
if(c == ' ' || c == '\t'){ if(c == ' ' || c == '\t'){
*p = '\0'; *p = '\0';
@ -321,9 +321,9 @@ static bool configParse(raconf inst, const char *fileName){
goto _strip_value_end_whities; goto _strip_value_end_whities;
} }
p++; p++;
} }
// Buildin Hook: // Buildin Hook:
if( stricmp(start, "import") == 0){ if( stricmp(start, "import") == 0){
if( configParse(inst, valuestart) != true){ if( configParse(inst, valuestart) != true){
@ -334,7 +334,7 @@ static bool configParse(raconf inst, const char *fileName){
struct conf_value *v, *o; struct conf_value *v, *o;
char key[ (SECTION_LEN+VARNAME_LEN+1+1) ]; //+1 for delimiter, +1 for termination. char key[ (SECTION_LEN+VARNAME_LEN+1+1) ]; //+1 for delimiter, +1 for termination.
size_t section_len; size_t section_len;
if(*currentSection == '\0'){ // empty / none if(*currentSection == '\0'){ // empty / none
strncpy(key, "<unnamed>",9); strncpy(key, "<unnamed>",9);
section_len = 9; section_len = 9;
@ -342,39 +342,39 @@ static bool configParse(raconf inst, const char *fileName){
strncpy(key, currentSection, currentSection_len); strncpy(key, currentSection, currentSection_len);
section_len = currentSection_len; section_len = currentSection_len;
} }
key[section_len] = '.'; // Delim
strncpy(&key[section_len+1], start, start_len);
key[section_len + start_len + 1] = '\0';
key[section_len] = '.'; // Delim
v = makeValue(key, valuestart, (p-valuestart) );
strncpy(&key[section_len+1], start, start_len);
key[section_len + start_len + 1] = '\0';
v = makeValue(key, valuestart, (p-valuestart) );
// Try to get the old one before // Try to get the old one before
o = strdb_get(inst->db, key); o = strdb_get(inst->db, key);
if(o != NULL){ if(o != NULL){
strdb_remove(inst->db, key); strdb_remove(inst->db, key);
aFree(o); // aFree(o); //
} }
strdb_put( inst->db, key, v); strdb_put( inst->db, key, v);
} }
}else{ }else{
ShowError("Syntax Error: unexpected Character '%c' in %s:%u (offset %u)\n", c, fileName, linecnt, (p-line) ); ShowError("Syntax Error: unexpected Character '%c' in %s:%u (offset %u)\n", c, fileName, linecnt, (p-line) );
fclose(fp); fclose(fp);
return false; return false;
} }
} }
fclose(fp); fclose(fp);
return true; return true;
}//end: configParse() }//end: configParse()
@ -395,24 +395,24 @@ static bool configParse(raconf inst, const char *fileName){
strncpy(&dest[section_len+1], key, key_len); \ strncpy(&dest[section_len+1], key, key_len); \
dest[section_len + key_len + 1] = '\0'; \ dest[section_len + key_len + 1] = '\0'; \
} }
raconf raconf_parse(const char *file_name){ raconf raconf_parse(const char *file_name){
struct raconf *rc; struct raconf *rc;
rc = aCalloc(1, sizeof(struct raconf) ); rc = aCalloc(1, sizeof(struct raconf) );
if(rc == NULL){ if(rc == NULL){
ShowFatalError("raconf_parse: failed to allocate memory for new handle\n"); ShowFatalError("raconf_parse: failed to allocate memory for new handle\n");
return NULL; return NULL;
} }
rc->db = strdb_alloc(DB_OPT_BASE | DB_OPT_DUP_KEY, 98); rc->db = strdb_alloc(DB_OPT_BASE | DB_OPT_DUP_KEY, 98);
// //
if(configParse(rc, file_name) != true){ if(configParse(rc, file_name) != true){
ShowError("Failed to Parse Configuration file '%s'\n", file_name); ShowError("Failed to Parse Configuration file '%s'\n", file_name);
} }
return rc; return rc;
}//end: raconf_parse() }//end: raconf_parse()
@ -420,7 +420,7 @@ raconf raconf_parse(const char *file_name){
void raconf_destroy(raconf rc){ void raconf_destroy(raconf rc){
DBIterator *iter; DBIterator *iter;
struct conf_value *v; struct conf_value *v;
// Clear all entrys in db. // Clear all entrys in db.
iter = db_iterator(rc->db); iter = db_iterator(rc->db);
for( v = (struct conf_value*)dbi_first(iter); dbi_exists(iter); v = (struct conf_value*)dbi_next(iter) ){ for( v = (struct conf_value*)dbi_first(iter); dbi_exists(iter); v = (struct conf_value*)dbi_next(iter) ){
@ -429,15 +429,15 @@ void raconf_destroy(raconf rc){
dbi_destroy(iter); dbi_destroy(iter);
db_destroy(rc->db); db_destroy(rc->db);
aFree(rc); aFree(rc);
}//end: raconf_destroy() }//end: raconf_destroy()
bool raconf_getbool(raconf rc, const char *section, const char *key, bool _default){ bool raconf_getbool(raconf rc, const char *section, const char *key, bool _default){
char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
struct conf_value *v; struct conf_value *v;
MAKEKEY(keystr, section, key); MAKEKEY(keystr, section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
@ -451,7 +451,7 @@ bool raconf_getbool(raconf rc, const char *section, const char *key, bool _defa
float raconf_getfloat(raconf rc,const char *section, const char *key, float _default){ float raconf_getfloat(raconf rc,const char *section, const char *key, float _default){
char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
struct conf_value *v; struct conf_value *v;
MAKEKEY(keystr, section, key); MAKEKEY(keystr, section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
@ -465,9 +465,9 @@ float raconf_getfloat(raconf rc,const char *section, const char *key, float _def
int64 raconf_getint(raconf rc, const char *section, const char *key, int64 _default){ int64 raconf_getint(raconf rc, const char *section, const char *key, int64 _default){
char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
struct conf_value *v; struct conf_value *v;
MAKEKEY(keystr, section, key); MAKEKEY(keystr, section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL) if(v == NULL)
return _default; return _default;
@ -481,7 +481,7 @@ const char* raconf_getstr(raconf rc, const char *section, const char *key, cons
char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
struct conf_value *v; struct conf_value *v;
MAKEKEY(keystr, section, key); MAKEKEY(keystr, section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL) if(v == NULL)
@ -494,11 +494,11 @@ const char* raconf_getstr(raconf rc, const char *section, const char *key, cons
bool raconf_getboolEx(raconf rc, const char *section, const char *fallback_section, const char *key, bool _default){ bool raconf_getboolEx(raconf rc, const char *section, const char *fallback_section, const char *key, bool _default){
char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
struct conf_value *v; struct conf_value *v;
MAKEKEY(keystr, section, key); MAKEKEY(keystr, section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL){ if(v == NULL){
MAKEKEY(keystr, fallback_section, key); MAKEKEY(keystr, fallback_section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL){ if(v == NULL){
@ -506,7 +506,7 @@ bool raconf_getboolEx(raconf rc, const char *section, const char *fallback_secti
}else{ }else{
return v->bval; return v->bval;
} }
}else{ }else{
return v->bval; return v->bval;
} }
@ -516,11 +516,11 @@ bool raconf_getboolEx(raconf rc, const char *section, const char *fallback_secti
float raconf_getfloatEx(raconf rc,const char *section, const char *fallback_section, const char *key, float _default){ float raconf_getfloatEx(raconf rc,const char *section, const char *fallback_section, const char *key, float _default){
char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
struct conf_value *v; struct conf_value *v;
MAKEKEY(keystr, section, key); MAKEKEY(keystr, section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL){ if(v == NULL){
MAKEKEY(keystr, fallback_section, key); MAKEKEY(keystr, fallback_section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL){ if(v == NULL){
@ -528,22 +528,22 @@ float raconf_getfloatEx(raconf rc,const char *section, const char *fallback_sect
}else{ }else{
return (float)v->floatval; return (float)v->floatval;
} }
}else{ }else{
return (float)v->floatval; return (float)v->floatval;
} }
}//end: raconf_getfloatEx() }//end: raconf_getfloatEx()
int64 raconf_getintEx(raconf rc, const char *section, const char *fallback_section, const char *key, int64 _default){ int64 raconf_getintEx(raconf rc, const char *section, const char *fallback_section, const char *key, int64 _default){
char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
struct conf_value *v; struct conf_value *v;
MAKEKEY(keystr, section, key); MAKEKEY(keystr, section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL){ if(v == NULL){
MAKEKEY(keystr, fallback_section, key); MAKEKEY(keystr, fallback_section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL){ if(v == NULL){
@ -551,7 +551,7 @@ int64 raconf_getintEx(raconf rc, const char *section, const char *fallback_sect
}else{ }else{
return v->intval; return v->intval;
} }
}else{ }else{
return v->intval; return v->intval;
} }
@ -562,11 +562,11 @@ int64 raconf_getintEx(raconf rc, const char *section, const char *fallback_sect
const char* raconf_getstrEx(raconf rc, const char *section, const char *fallback_section, const char *key, const char *_default){ const char* raconf_getstrEx(raconf rc, const char *section, const char *fallback_section, const char *key, const char *_default){
char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1]; char keystr[SECTION_LEN + VARNAME_LEN + 1 + 1];
struct conf_value *v; struct conf_value *v;
MAKEKEY(keystr, section, key); MAKEKEY(keystr, section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL){ if(v == NULL){
MAKEKEY(keystr, fallback_section, key); MAKEKEY(keystr, fallback_section, key);
v = strdb_get(rc->db, keystr); v = strdb_get(rc->db, keystr);
if(v == NULL){ if(v == NULL){
@ -574,7 +574,7 @@ const char* raconf_getstrEx(raconf rc, const char *section, const char *fallbac
}else{ }else{
return v->strval; return v->strval;
} }
}else{ }else{
return v->strval; return v->strval;
} }

View File

@ -7,8 +7,8 @@
#include "cbasetypes.h" #include "cbasetypes.h"
// rAthena generic configuration file parser // rAthena generic configuration file parser
// //
// Config file Syntax is athena style // Config file Syntax is athena style
// extended with ini style support (including sections) // extended with ini style support (including sections)
// //
// Comments are started with // or ; (ini style) // Comments are started with // or ; (ini style)
@ -17,9 +17,9 @@
typedef struct raconf *raconf; typedef struct raconf *raconf;
/** /**
* Parses a rAthna Configuration file * Parses a rAthna Configuration file
* *
* @param file_name path to the file to parse * @param file_name path to the file to parse
* *
* @returns not NULL incase of success * @returns not NULL incase of success
@ -27,7 +27,7 @@ typedef struct raconf *raconf;
raconf raconf_parse(const char *file_name); raconf raconf_parse(const char *file_name);
/** /**
* Frees a Handle received from raconf_parse * Frees a Handle received from raconf_parse
* *
* @param rc - the handle to free * @param rc - the handle to free
@ -35,17 +35,17 @@ raconf raconf_parse(const char *file_name);
void raconf_destroy(raconf rc); void raconf_destroy(raconf rc);
/** /**
* Gets the value for Section / Key pair, if key not exists returns _default! * Gets the value for Section / Key pair, if key not exists returns _default!
* *
*/ */
bool raconf_getbool(raconf rc, const char *section, const char *key, bool _default); bool raconf_getbool(raconf rc, const char *section, const char *key, bool _default);
float raconf_getfloat(raconf rc,const char *section, const char *key, float _default); float raconf_getfloat(raconf rc,const char *section, const char *key, float _default);
int64 raconf_getint(raconf rc, const char *section, const char *key, int64 _default); int64 raconf_getint(raconf rc, const char *section, const char *key, int64 _default);
const char* raconf_getstr(raconf rc, const char *section, const char *key, const char *_default); const char* raconf_getstr(raconf rc, const char *section, const char *key, const char *_default);
/** /**
* Gets the value for Section / Key pair, but has fallback section option if not found in section, * Gets the value for Section / Key pair, but has fallback section option if not found in section,
* if not found in both - default gets returned. * if not found in both - default gets returned.
* *
*/ */

View File

@ -99,7 +99,7 @@ char console_log_filepath[32] = "./log/unknown.log";
// ansi compatible printf with control sequence parser for windows // ansi compatible printf with control sequence parser for windows
// fast hack, handle with care, not everything implemented // fast hack, handle with care, not everything implemented
// //
// \033[#;...;#m - Set Graphics Rendition (SGR) // \033[#;...;#m - Set Graphics Rendition (SGR)
// //
// printf("\x1b[1;31;40m"); // Bright red on black // printf("\x1b[1;31;40m"); // Bright red on black
// printf("\x1b[3;33;45m"); // Blinking yellow on magenta (blink not implemented) // printf("\x1b[3;33;45m"); // Blinking yellow on magenta (blink not implemented)
@ -118,19 +118,19 @@ char console_log_filepath[32] = "./log/unknown.log";
// 8 - Concealed (invisible) // 8 - Concealed (invisible)
// //
// \033[#A - Cursor Up (CUU) // \033[#A - Cursor Up (CUU)
// Moves the cursor up by the specified number of lines without changing columns. // Moves the cursor up by the specified number of lines without changing columns.
// If the cursor is already on the top line, this sequence is ignored. \e[A is equivalent to \e[1A. // If the cursor is already on the top line, this sequence is ignored. \e[A is equivalent to \e[1A.
// //
// \033[#B - Cursor Down (CUD) // \033[#B - Cursor Down (CUD)
// Moves the cursor down by the specified number of lines without changing columns. // Moves the cursor down by the specified number of lines without changing columns.
// If the cursor is already on the bottom line, this sequence is ignored. \e[B is equivalent to \e[1B. // If the cursor is already on the bottom line, this sequence is ignored. \e[B is equivalent to \e[1B.
// //
// \033[#C - Cursor Forward (CUF) // \033[#C - Cursor Forward (CUF)
// Moves the cursor forward by the specified number of columns without changing lines. // Moves the cursor forward by the specified number of columns without changing lines.
// If the cursor is already in the rightmost column, this sequence is ignored. \e[C is equivalent to \e[1C. // If the cursor is already in the rightmost column, this sequence is ignored. \e[C is equivalent to \e[1C.
// //
// \033[#D - Cursor Backward (CUB) // \033[#D - Cursor Backward (CUB)
// Moves the cursor back by the specified number of columns without changing lines. // Moves the cursor back by the specified number of columns without changing lines.
// If the cursor is already in the leftmost column, this sequence is ignored. \e[D is equivalent to \e[1D. // If the cursor is already in the leftmost column, this sequence is ignored. \e[D is equivalent to \e[1D.
// //
// \033[#E - Cursor Next Line (CNL) // \033[#E - Cursor Next Line (CNL)
@ -143,15 +143,15 @@ char console_log_filepath[32] = "./log/unknown.log";
// Moves the cursor to indicated column in current row. \e[G is equivalent to \e[1G. // Moves the cursor to indicated column in current row. \e[G is equivalent to \e[1G.
// //
// \033[#;#H - Cursor Position (CUP) // \033[#;#H - Cursor Position (CUP)
// Moves the cursor to the specified position. The first # specifies the line number, // Moves the cursor to the specified position. The first # specifies the line number,
// the second # specifies the column. If you do not specify a position, the cursor moves to the home position: // the second # specifies the column. If you do not specify a position, the cursor moves to the home position:
// the upper-left corner of the screen (line 1, column 1). // the upper-left corner of the screen (line 1, column 1).
// //
// \033[#;#f - Horizontal & Vertical Position // \033[#;#f - Horizontal & Vertical Position
// (same as \033[#;#H) // (same as \033[#;#H)
// //
// \033[s - Save Cursor Position (SCP) // \033[s - Save Cursor Position (SCP)
// The current cursor position is saved. // The current cursor position is saved.
// //
// \033[u - Restore cursor position (RCP) // \033[u - Restore cursor position (RCP)
// Restores the cursor position saved with the (SCP) sequence \033[s. // Restores the cursor position saved with the (SCP) sequence \033[s.
@ -221,7 +221,7 @@ int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
WriteFile(handle, p, (DWORD)(q-p), &written, 0); WriteFile(handle, p, (DWORD)(q-p), &written, 0);
if( q[1]!='[' ) if( q[1]!='[' )
{ // write the escape char (whatever purpose it has) { // write the escape char (whatever purpose it has)
if(0==WriteConsole(handle, q, 1, &written, 0) ) if(0==WriteConsole(handle, q, 1, &written, 0) )
WriteFile(handle,q, 1, &written, 0); WriteFile(handle,q, 1, &written, 0);
p=q+1; //and start searching again p=q+1; //and start searching again
@ -241,7 +241,7 @@ int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
q=q+2; q=q+2;
for(;;) for(;;)
{ {
if( ISDIGIT(*q) ) if( ISDIGIT(*q) )
{ // add number to number array, only accept 2digits, shift out the rest { // add number to number array, only accept 2digits, shift out the rest
// so // \033[123456789m will become \033[89m // so // \033[123456789m will become \033[89m
numbers[numpoint] = (numbers[numpoint]<<4) | (*q-'0'); numbers[numpoint] = (numbers[numpoint]<<4) | (*q-'0');
@ -358,12 +358,12 @@ int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
else if(num==2) else if(num==2)
{ // Number of chars on screen. { // Number of chars on screen.
cnt = info.dwSize.X * info.dwSize.Y; cnt = info.dwSize.X * info.dwSize.Y;
SetConsoleCursorPosition(handle, origin); SetConsoleCursorPosition(handle, origin);
} }
else// 0 and default else// 0 and default
{ // number of chars from cursor to end { // number of chars from cursor to end
origin = info.dwCursorPosition; origin = info.dwCursorPosition;
cnt = info.dwSize.X * (info.dwSize.Y - info.dwCursorPosition.Y) - info.dwCursorPosition.X; cnt = info.dwSize.X * (info.dwSize.Y - info.dwCursorPosition.Y) - info.dwCursorPosition.X;
} }
FillConsoleOutputAttribute(handle, info.wAttributes, cnt, origin, &tmp); FillConsoleOutputAttribute(handle, info.wAttributes, cnt, origin, &tmp);
FillConsoleOutputCharacter(handle, ' ', cnt, origin, &tmp); FillConsoleOutputCharacter(handle, ' ', cnt, origin, &tmp);
@ -397,7 +397,7 @@ int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
else if( *q == 'H' || *q == 'f' ) else if( *q == 'H' || *q == 'f' )
{ // \033[#;#H - Cursor Position (CUP) { // \033[#;#H - Cursor Position (CUP)
// \033[#;#f - Horizontal & Vertical Position // \033[#;#f - Horizontal & Vertical Position
// The first # specifies the line number, the second # specifies the column. // The first # specifies the line number, the second # specifies the column.
// The default for both is 1 // The default for both is 1
info.dwCursorPosition.X = (numbers[numpoint])?(numbers[numpoint]>>4)*10+((numbers[numpoint]&0x0F)-1):0; info.dwCursorPosition.X = (numbers[numpoint])?(numbers[numpoint]>>4)*10+((numbers[numpoint]&0x0F)-1):0;
info.dwCursorPosition.Y = (numpoint && numbers[numpoint-1])?(numbers[numpoint-1]>>4)*10+((numbers[numpoint-1]&0x0F)-1):0; info.dwCursorPosition.Y = (numpoint && numbers[numpoint-1])?(numbers[numpoint-1]>>4)*10+((numbers[numpoint-1]&0x0F)-1):0;
@ -494,7 +494,7 @@ int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
--q; --q;
} }
// skip the sequencer and search again // skip the sequencer and search again
p = q+1; p = q+1;
break; break;
}// end while }// end while
} }
@ -550,7 +550,7 @@ int VFPRINTF(FILE *file, const char *fmt, va_list argptr)
{ // find the escape character { // find the escape character
fprintf(file, "%.*s", (int)(q-p), p); // write up to the escape fprintf(file, "%.*s", (int)(q-p), p); // write up to the escape
if( q[1]!='[' ) if( q[1]!='[' )
{ // write the escape char (whatever purpose it has) { // write the escape char (whatever purpose it has)
fprintf(file, "%.*s", 1, q); fprintf(file, "%.*s", 1, q);
p=q+1; //and start searching again p=q+1; //and start searching again
} }
@ -563,7 +563,7 @@ int VFPRINTF(FILE *file, const char *fmt, va_list argptr)
q=q+2; q=q+2;
while(1) while(1)
{ {
if( ISDIGIT(*q) ) if( ISDIGIT(*q) )
{ {
++q; ++q;
// and next character // and next character
@ -632,7 +632,7 @@ int VFPRINTF(FILE *file, const char *fmt, va_list argptr)
--q; --q;
} }
// skip the sequencer and search again // skip the sequencer and search again
p = q+1; p = q+1;
break; break;
}// end while }// end while
} }
@ -668,7 +668,7 @@ int _vShowMessage(enum msg_type flag, const char *string, va_list ap)
#if defined(DEBUGLOGMAP) || defined(DEBUGLOGCHAR) || defined(DEBUGLOGLOGIN) #if defined(DEBUGLOGMAP) || defined(DEBUGLOGCHAR) || defined(DEBUGLOGLOGIN)
FILE *fp; FILE *fp;
#endif #endif
if (!string || *string == '\0') { if (!string || *string == '\0') {
ShowError("Empty string passed to _vShowMessage().\n"); ShowError("Empty string passed to _vShowMessage().\n");
return 1; return 1;

View File

@ -867,7 +867,7 @@ int do_sockets(int next)
if (last_tick != socket_data_last_tick) if (last_tick != socket_data_last_tick)
{ {
char buf[1024]; char buf[1024];
sprintf(buf, "In: %.03f kB/s (%.03f kB/s, Q: %.03f kB) | Out: %.03f kB/s (%.03f kB/s, Q: %.03f kB) | RAM: %.03f MB", socket_data_i/1024., socket_data_ci/1024., socket_data_qi/1024., socket_data_o/1024., socket_data_co/1024., socket_data_qo/1024., malloc_usage()/1024.); sprintf(buf, "In: %.03f kB/s (%.03f kB/s, Q: %.03f kB) | Out: %.03f kB/s (%.03f kB/s, Q: %.03f kB) | RAM: %.03f MB", socket_data_i/1024., socket_data_ci/1024., socket_data_qi/1024., socket_data_o/1024., socket_data_co/1024., socket_data_qo/1024., malloc_usage()/1024.);
#ifdef _WIN32 #ifdef _WIN32
SetConsoleTitle(buf); SetConsoleTitle(buf);
@ -1244,7 +1244,7 @@ int socket_getips(uint32* ips, int max)
#ifdef WIN32 #ifdef WIN32
{ {
char fullhost[255]; char fullhost[255];
// XXX This should look up the local IP addresses in the registry // XXX This should look up the local IP addresses in the registry
// instead of calling gethostbyname. However, the way IP addresses // instead of calling gethostbyname. However, the way IP addresses

View File

@ -14,7 +14,7 @@
// For more information, see LICENCE in the main folder // For more information, see LICENCE in the main folder
// //
// //
#ifdef WIN32 #ifdef WIN32
#include "winapi.h" #include "winapi.h"
#endif #endif
@ -34,7 +34,7 @@ typedef struct __declspec( align(64) ) SPIN_LOCK{
typedef struct SPIN_LOCK{ typedef struct SPIN_LOCK{
volatile int32 lock; volatile int32 lock;
volatile int32 nest; // nesting level. volatile int32 nest; // nesting level.
volatile int32 sync_lock; volatile int32 sync_lock;
} __attribute__((aligned(64))) SPIN_LOCK, *PSPIN_LOCK; } __attribute__((aligned(64))) SPIN_LOCK, *PSPIN_LOCK;
#endif #endif
@ -57,8 +57,8 @@ static forceinline void FinalizeSpinLock(PSPIN_LOCK lck){
static forceinline void EnterSpinLock(PSPIN_LOCK lck){ static forceinline void EnterSpinLock(PSPIN_LOCK lck){
int tid = rathread_get_tid(); int tid = rathread_get_tid();
// Get Sync Lock && Check if the requester thread already owns the lock. // Get Sync Lock && Check if the requester thread already owns the lock.
// if it owns, increase nesting level // if it owns, increase nesting level
getsynclock(&lck->sync_lock); getsynclock(&lck->sync_lock);
if(InterlockedCompareExchange(&lck->lock, tid, tid) == tid){ if(InterlockedCompareExchange(&lck->lock, tid, tid) == tid){
@ -68,17 +68,17 @@ static forceinline void EnterSpinLock(PSPIN_LOCK lck){
} }
// drop sync lock // drop sync lock
dropsynclock(&lck->sync_lock); dropsynclock(&lck->sync_lock);
// Spin until we've got it ! // Spin until we've got it !
while(1){ while(1){
if(InterlockedCompareExchange(&lck->lock, tid, 0) == 0){ if(InterlockedCompareExchange(&lck->lock, tid, 0) == 0){
InterlockedIncrement(&lck->nest); InterlockedIncrement(&lck->nest);
return; // Got Lock return; // Got Lock
} }
rathread_yield(); // Force ctxswitch to another thread. rathread_yield(); // Force ctxswitch to another thread.
} }
@ -89,12 +89,12 @@ static forceinline void LeaveSpinLock(PSPIN_LOCK lck){
int tid = rathread_get_tid(); int tid = rathread_get_tid();
getsynclock(&lck->sync_lock); getsynclock(&lck->sync_lock);
if(InterlockedCompareExchange(&lck->lock, tid, tid) == tid){ // this thread owns the lock. if(InterlockedCompareExchange(&lck->lock, tid, tid) == tid){ // this thread owns the lock.
if(InterlockedDecrement(&lck->nest) == 0) if(InterlockedDecrement(&lck->nest) == 0)
InterlockedExchange(&lck->lock, 0); // Unlock! InterlockedExchange(&lck->lock, 0); // Unlock!
} }
dropsynclock(&lck->sync_lock); dropsynclock(&lck->sync_lock);
} }

View File

@ -94,7 +94,7 @@ static int Sql_P_Keepalive(Sql* self);
* @param host : hostname * @param host : hostname
* @param port : port * @param port : port
* @param db : schema name * @param db : schema name
* @return * @return
*/ */
int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* host, uint16 port, const char* db) int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* host, uint16 port, const char* db)
{ {

View File

@ -210,10 +210,10 @@ void Sql_Free(Sql* self);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Prepared Statements // Prepared Statements
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Parameters are placed in the statement by embedding question mark ('?') // Parameters are placed in the statement by embedding question mark ('?')
// characters into the query at the appropriate positions. // characters into the query at the appropriate positions.
// The markers are legal only in places where they represent data. // The markers are legal only in places where they represent data.
// The markers cannot be inside quotes. Quotes will be added automatically // The markers cannot be inside quotes. Quotes will be added automatically
// when they are required. // when they are required.
// //
// example queries with parameters: // example queries with parameters:
@ -298,7 +298,7 @@ size_t SqlStmt_NumColumns(SqlStmt* self);
/// Binds the result of a column to a buffer. /// Binds the result of a column to a buffer.
/// The buffer will be filled with data when the next row is fetched. /// The buffer will be filled with data when the next row is fetched.
/// For string/enum buffer types there has to be enough space for the data /// For string/enum buffer types there has to be enough space for the data
/// and the nul-terminator (an extra byte). /// and the nul-terminator (an extra byte).
/// ///
/// @return SQL_SUCCESS or SQL_ERROR /// @return SQL_SUCCESS or SQL_ERROR

View File

@ -9,7 +9,7 @@
#ifdef WIN32 #ifdef WIN32
#include "winapi.h" #include "winapi.h"
#define getpagesize() 4096 // @TODO: implement this properly (GetSystemInfo .. dwPageSize..). (Atm as on all supported win platforms its 4k its static.) #define getpagesize() 4096 // @TODO: implement this properly (GetSystemInfo .. dwPageSize..). (Atm as on all supported win platforms its 4k its static.)
#define __thread __declspec( thread ) #define __thread __declspec( thread )
#else #else
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
@ -25,8 +25,8 @@
#include "thread.h" #include "thread.h"
// When Compiling using MSC (on win32..) we know we have support in any case! // When Compiling using MSC (on win32..) we know we have support in any case!
#ifdef _MSC_VER #ifdef _MSC_VER
#define HAS_TLS #define HAS_TLS
#endif #endif
@ -34,10 +34,10 @@
struct rAthread { struct rAthread {
unsigned int myID; unsigned int myID;
RATHREAD_PRIO prio; RATHREAD_PRIO prio;
rAthreadProc proc; rAthreadProc proc;
void *param; void *param;
#ifdef WIN32 #ifdef WIN32
HANDLE hThread; HANDLE hThread;
@ -60,7 +60,7 @@ static struct rAthread l_threads[RA_THREADS_MAX];
void rathread_init(){ void rathread_init(){
register unsigned int i; register unsigned int i;
memset(&l_threads, 0x00, RA_THREADS_MAX * sizeof(struct rAthread) ); memset(&l_threads, 0x00, RA_THREADS_MAX * sizeof(struct rAthread) );
for(i = 0; i < RA_THREADS_MAX; i++){ for(i = 0; i < RA_THREADS_MAX; i++){
l_threads[i].myID = i; l_threads[i].myID = i;
} }
@ -78,10 +78,10 @@ void rathread_init(){
void rathread_final(){ void rathread_final(){
register unsigned int i; register unsigned int i;
// Unterminated Threads Left? // Unterminated Threads Left?
// Should'nt happen .. // Should'nt happen ..
// Kill 'em all! // Kill 'em all!
// //
for(i = 1; i < RA_THREADS_MAX; i++){ for(i = 1; i < RA_THREADS_MAX; i++){
if(l_threads[i].proc != NULL){ if(l_threads[i].proc != NULL){
@ -89,8 +89,8 @@ void rathread_final(){
rathread_destroy(&l_threads[i]); rathread_destroy(&l_threads[i]);
} }
} }
}//end: rathread_final() }//end: rathread_final()
@ -102,7 +102,7 @@ static void rat_thread_terminated( rAthread handle ){
// Simply set all members to 0 (except the id) // Simply set all members to 0 (except the id)
memset(handle, 0x00, sizeof(struct rAthread)); memset(handle, 0x00, sizeof(struct rAthread));
handle->myID = id_backup; // done ;) handle->myID = id_backup; // done ;)
}//end: rat_thread_terminated() }//end: rat_thread_terminated()
@ -114,15 +114,15 @@ static void *_raThreadMainRedirector( void *p ){
sigset_t set; // on Posix Thread platforms sigset_t set; // on Posix Thread platforms
#endif #endif
void *ret; void *ret;
// Update myID @ TLS to right id. // Update myID @ TLS to right id.
#ifdef HAS_TLS #ifdef HAS_TLS
g_rathread_ID = ((rAthread)p)->myID; g_rathread_ID = ((rAthread)p)->myID;
#endif #endif
#ifndef WIN32 #ifndef WIN32
// When using posix threads // When using posix threads
// the threads inherits the Signal mask from the thread which's spawned // the threads inherits the Signal mask from the thread which's spawned
// this thread // this thread
// so we've to block everything we dont care about. // so we've to block everything we dont care about.
sigemptyset(&set); sigemptyset(&set);
@ -131,13 +131,13 @@ static void *_raThreadMainRedirector( void *p ){
sigaddset(&set, SIGPIPE); sigaddset(&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, NULL); pthread_sigmask(SIG_BLOCK, &set, NULL);
#endif #endif
ret = ((rAthread)p)->proc( ((rAthread)p)->param ) ; ret = ((rAthread)p)->proc( ((rAthread)p)->param ) ;
#ifdef WIN32 #ifdef WIN32
CloseHandle( ((rAthread)p)->hThread ); CloseHandle( ((rAthread)p)->hThread );
#endif #endif
@ -155,7 +155,7 @@ static void *_raThreadMainRedirector( void *p ){
/// ///
/// API Level /// API Level
/// ///
rAthread rathread_create( rAthreadProc entryPoint, void *param ){ rAthread rathread_create( rAthreadProc entryPoint, void *param ){
return rathread_createEx( entryPoint, param, (1<<23) /*8MB*/, RAT_PRIO_NORMAL ); return rathread_createEx( entryPoint, param, (1<<23) /*8MB*/, RAT_PRIO_NORMAL );
}//end: rathread_create() }//end: rathread_create()
@ -176,21 +176,21 @@ rAthread rathread_createEx( rAthreadProc entryPoint, void *param, size_t szSta
szStack += tmp; szStack += tmp;
// Get a free Thread Slot. // Get a free Thread Slot.
for(i = 0; i < RA_THREADS_MAX; i++){ for(i = 0; i < RA_THREADS_MAX; i++){
if(l_threads[i].proc == NULL){ if(l_threads[i].proc == NULL){
handle = &l_threads[i]; handle = &l_threads[i];
break; break;
} }
} }
if(handle == NULL){ if(handle == NULL){
ShowError("rAthread: cannot create new thread (entryPoint: %p) - no free thread slot found!", entryPoint); ShowError("rAthread: cannot create new thread (entryPoint: %p) - no free thread slot found!", entryPoint);
return NULL; return NULL;
} }
handle->proc = entryPoint; handle->proc = entryPoint;
handle->param = param; handle->param = param;
@ -199,7 +199,7 @@ rAthread rathread_createEx( rAthreadProc entryPoint, void *param, size_t szSta
#else #else
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, szStack); pthread_attr_setstacksize(&attr, szStack);
if(pthread_create(&handle->hThread, &attr, _raThreadMainRedirector, (void*)handle) != 0){ if(pthread_create(&handle->hThread, &attr, _raThreadMainRedirector, (void*)handle) != 0){
handle->proc = NULL; handle->proc = NULL;
handle->param = NULL; handle->param = NULL;
@ -209,7 +209,7 @@ rAthread rathread_createEx( rAthreadProc entryPoint, void *param, size_t szSta
#endif #endif
rathread_prio_set( handle, prio ); rathread_prio_set( handle, prio );
return handle; return handle;
}//end: rathread_createEx }//end: rathread_createEx
@ -222,11 +222,11 @@ void rathread_destroy ( rAthread handle ){
} }
#else #else
if( pthread_cancel( handle->hThread ) == 0){ if( pthread_cancel( handle->hThread ) == 0){
// We have to join it, otherwise pthread wont re-cycle its internal ressources assoc. with this thread. // We have to join it, otherwise pthread wont re-cycle its internal ressources assoc. with this thread.
// //
pthread_join( handle->hThread, NULL ); pthread_join( handle->hThread, NULL );
// Tell our manager to release ressources ;) // Tell our manager to release ressources ;)
rat_thread_terminated(handle); rat_thread_terminated(handle);
} }
@ -236,11 +236,11 @@ void rathread_destroy ( rAthread handle ){
rAthread rathread_self( ){ rAthread rathread_self( ){
#ifdef HAS_TLS #ifdef HAS_TLS
rAthread handle = &l_threads[g_rathread_ID]; rAthread handle = &l_threads[g_rathread_ID];
if(handle->proc != NULL) // entry point set, so its used! if(handle->proc != NULL) // entry point set, so its used!
return handle; return handle;
#else #else
// .. so no tls means we have to search the thread by its api-handle .. // .. so no tls means we have to search the thread by its api-handle ..
int i; int i;
#ifdef WIN32 #ifdef WIN32
@ -250,21 +250,21 @@ rAthread rathread_self( ){
pthread_t hSelf; pthread_t hSelf;
hSelf = pthread_self(); hSelf = pthread_self();
#endif #endif
for(i = 0; i < RA_THREADS_MAX; i++){ for(i = 0; i < RA_THREADS_MAX; i++){
if(l_threads[i].hThread == hSelf && l_threads[i].proc != NULL) if(l_threads[i].hThread == hSelf && l_threads[i].proc != NULL)
return &l_threads[i]; return &l_threads[i];
} }
#endif #endif
return NULL; return NULL;
}//end: rathread_self() }//end: rathread_self()
int rathread_get_tid(){ int rathread_get_tid(){
#ifdef HAS_TLS #ifdef HAS_TLS
return g_rathread_ID; return g_rathread_ID;
#else #else
// todo // todo
@ -273,21 +273,21 @@ int rathread_get_tid(){
#else #else
return (intptr_t)pthread_self(); return (intptr_t)pthread_self();
#endif #endif
#endif #endif
}//end: rathread_get_tid() }//end: rathread_get_tid()
bool rathread_wait( rAthread handle, void* *out_exitCode ){ bool rathread_wait( rAthread handle, void* *out_exitCode ){
// Hint: // Hint:
// no thread data cleanup routine call here! // no thread data cleanup routine call here!
// its managed by the callProxy itself.. // its managed by the callProxy itself..
// //
#ifdef WIN32 #ifdef WIN32
WaitForSingleObject(handle->hThread, INFINITE); WaitForSingleObject(handle->hThread, INFINITE);
return true; return true;
#else #else
if(pthread_join(handle->hThread, out_exitCode) == 0) if(pthread_join(handle->hThread, out_exitCode) == 0)
return true; return true;
@ -298,8 +298,8 @@ bool rathread_wait( rAthread handle, void* *out_exitCode ){
void rathread_prio_set( rAthread handle, RATHREAD_PRIO prio ){ void rathread_prio_set( rAthread handle, RATHREAD_PRIO prio ){
handle->prio = RAT_PRIO_NORMAL; handle->prio = RAT_PRIO_NORMAL;
//@TODO //@TODO
}//end: rathread_prio_set() }//end: rathread_prio_set()
@ -309,9 +309,9 @@ RATHREAD_PRIO rathread_prio_get( rAthread handle){
void rathread_yield(){ void rathread_yield(){
#ifdef WIN32 #ifdef WIN32
SwitchToThread(); SwitchToThread();
#else #else
sched_yield(); sched_yield();
#endif #endif
}//end: rathread_yield() }//end: rathread_yield()

View File

@ -1,7 +1,7 @@
// Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL // Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL
// For more information, see LICENCE in the main folder // For more information, see LICENCE in the main folder
#pragma once #pragma once
#ifndef _rA_THREAD_H_ #ifndef _rA_THREAD_H_
#define _rA_THREAD_H_ #define _rA_THREAD_H_
@ -13,7 +13,7 @@ typedef void* (*rAthreadProc)(void*);
typedef enum RATHREAD_PRIO { typedef enum RATHREAD_PRIO {
RAT_PRIO_LOW = 0, RAT_PRIO_LOW = 0,
RAT_PRIO_NORMAL, RAT_PRIO_NORMAL,
RAT_PRIO_HIGH RAT_PRIO_HIGH
} RATHREAD_PRIO; } RATHREAD_PRIO;
@ -22,18 +22,18 @@ typedef enum RATHREAD_PRIO {
* *
* @param entyPoint - entryProc, * @param entyPoint - entryProc,
* @param param - general purpose parameter, would be given as parameter to the thread's entrypoint. * @param param - general purpose parameter, would be given as parameter to the thread's entrypoint.
* *
* @return not NULL if success * @return not NULL if success
*/ */
rAthread rathread_create( rAthreadProc entryPoint, void *param ); rAthread rathread_create( rAthreadProc entryPoint, void *param );
/** /**
* Creates a new Thread (with more creation options) * Creates a new Thread (with more creation options)
* *
* @param entyPoint - entryProc, * @param entyPoint - entryProc,
* @param param - general purpose parameter, would be given as parameter to the thread's entrypoint * @param param - general purpose parameter, would be given as parameter to the thread's entrypoint
* @param szStack - stack Size in bytes * @param szStack - stack Size in bytes
* @param prio - Priority of the Thread @ OS Scheduler.. * @param prio - Priority of the Thread @ OS Scheduler..
* *
* @return not NULL if success * @return not NULL if success
@ -44,29 +44,29 @@ rAthread rathread_createEx( rAthreadProc entryPoint, void *param, size_t szSta
/** /**
* Destroys the given Thread immediatly * Destroys the given Thread immediatly
* *
* @note The Handle gets invalid after call! dont use it afterwards. * @note The Handle gets invalid after call! dont use it afterwards.
* *
* @param handle - thread to destroy. * @param handle - thread to destroy.
*/ */
void rathread_destroy ( rAthread handle ); void rathread_destroy ( rAthread handle );
/** /**
* Returns the thread handle of the thread calling this function * Returns the thread handle of the thread calling this function
* *
* @note this wont work @ programms main thread * @note this wont work @ programms main thread
* @note the underlying implementation might not perform very well, cache the value received! * @note the underlying implementation might not perform very well, cache the value received!
* *
* @return not NULL if success * @return not NULL if success
*/ */
rAthread rathread_self( ); rAthread rathread_self( );
/** /**
* Returns own thrad id (TID) * Returns own thrad id (TID)
* *
* @note this is an unique identifier for the calling thread, and * @note this is an unique identifier for the calling thread, and
* depends on platfrom / compiler, and may not be the systems Thread ID! * depends on platfrom / compiler, and may not be the systems Thread ID!
* *
* @return -1 when fails, otherwise >= 0 * @return -1 when fails, otherwise >= 0
*/ */
@ -74,26 +74,26 @@ int rathread_get_tid();
/** /**
* Waits for the given thread to terminate * Waits for the given thread to terminate
* *
* @param handle - thread to wait (join) for * @param handle - thread to wait (join) for
* @param out_Exitcode - [OPTIONAL] - if given => Exitcode (value) of the given thread - if it's terminated * @param out_Exitcode - [OPTIONAL] - if given => Exitcode (value) of the given thread - if it's terminated
* *
* @return true - if the given thread has been terminated. * @return true - if the given thread has been terminated.
*/ */
bool rathread_wait( rAthread handle, void* *out_exitCode ); bool rathread_wait( rAthread handle, void* *out_exitCode );
/** /**
* Sets the given PRIORITY @ OS Task Scheduler * Sets the given PRIORITY @ OS Task Scheduler
* *
* @param handle - thread to set prio for * @param handle - thread to set prio for
* @param rio - the priority (RAT_PRIO_LOW ... ) * @param rio - the priority (RAT_PRIO_LOW ... )
*/ */
void rathread_prio_set( rAthread handle, RATHREAD_PRIO prio ); void rathread_prio_set( rAthread handle, RATHREAD_PRIO prio );
/** /**
* Gets the current Prio of the given trhead * Gets the current Prio of the given trhead
* *
* @param handle - the thread to get the prio for. * @param handle - the thread to get the prio for.
@ -103,9 +103,9 @@ RATHREAD_PRIO rathread_prio_get( rAthread handle);
/** /**
* Tells the OS scheduler to yield the execution of the calling thread * Tells the OS scheduler to yield the execution of the calling thread
* *
* @note: this will not "pause" the thread, * @note: this will not "pause" the thread,
* it just allows the OS to spent the remaining time * it just allows the OS to spent the remaining time
* of the slice to another thread. * of the slice to another thread.
*/ */
void rathread_yield(); void rathread_yield();

View File

@ -427,7 +427,7 @@ void split_time(int timein, int* year, int* month, int* day, int* hour, int* min
const int factor_min = 60; const int factor_min = 60;
const int factor_hour = factor_min*60; const int factor_hour = factor_min*60;
const int factor_day = factor_hour*24; const int factor_day = factor_hour*24;
const int factor_month = 2629743; // Approx (30.44 days) const int factor_month = 2629743; // Approx (30.44 days)
const int factor_year = 31556926; // Approx (365.24 days) const int factor_year = 31556926; // Approx (365.24 days)
*year = timein/factor_year; *year = timein/factor_year;
@ -459,7 +459,7 @@ double solve_time(char* modif_p) {
time_t now = time(NULL); time_t now = time(NULL);
time_t then = now; time_t then = now;
then_tm = *localtime(&then); then_tm = *localtime(&then);
nullpo_retr(0,modif_p); nullpo_retr(0,modif_p);
while (modif_p[0] != '\0') { while (modif_p[0] != '\0') {

View File

@ -60,7 +60,7 @@ void ShowDump(const void* buffer, size_t length)
ShowDebug("--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n"); ShowDebug("--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n");
ascii[16] = 0; ascii[16] = 0;
for( i = 0; i < length; i++ ) for( i = 0; i < length; i++ )
{ {
char c = RBUFB(buffer,i); char c = RBUFB(buffer,i);

View File

@ -7,7 +7,7 @@
#define WINVER 0x0500 #define WINVER 0x0500
#define _WIN32_IE 0x0600 #define _WIN32_IE 0x0600
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define NOCOMM #define NOCOMM
#define NOKANJI #define NOKANJI
#define NOHELP #define NOHELP
#define NOMCX #define NOMCX