Trimmed trailing whitespaces in /src/common
This commit is contained in:
parent
366aeeaafe
commit
cc9d08538a
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 ) { \
|
||||||
|
|||||||
@ -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.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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()
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 );
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -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)));
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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') {
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user