Trimmed trailing whitespaces in /src/common

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

View File

@ -4,16 +4,16 @@
#ifndef _rA_ATOMIC_H_
#define _rA_ATOMIC_H_
// Atomic Operations
// Atomic Operations
// (Interlocked CompareExchange, Add .. and so on ..)
//
//
// Implementation varies / depends on:
// - Architecture
// - Compiler
// - Operating System
//
// our Abstraction is fully API-Compatible to Microsofts implementation @ NT5.0+
//
//
#include "cbasetypes.h"
#if defined(_MSC_VER)
@ -29,14 +29,14 @@ forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch,
_asm{
lea esi,_cmp;
lea edi,exch;
mov eax,[esi];
mov edx,4[esi];
mov ebx,[edi];
mov ecx,4[edi];
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__)
// 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/
#if !defined(__x86_64__) && !defined(__i386__) \
&& ( !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
#endif

View File

@ -62,7 +62,7 @@ void config_setting_copy_elem(config_setting_t *parent, const config_setting_t *
config_setting_set_format(set, src->format);
} else if (CONFIG_TYPE_INT64 == config_setting_type(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)) {
config_setting_set_float_elem(parent, -1, config_setting_get_float(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;
n = config_setting_length(src);
for (i = 0; i < n; i++) {
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 {
config_setting_copy_elem(newAgg, config_setting_get_elem(src, i));
}

View File

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

View File

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

View File

@ -16,7 +16,7 @@ struct EVDP_DATA{
enum EVDP_EVENTFLAGS{
EVDP_EVENT_IN = 1, // Incomming data
EVDP_EVENT_IN = 1, // Incomming data
EVDP_EVENT_OUT = 2, // Connection accepts writing.
EVDP_EVENT_HUP = 4 // Connection Closed.
};
@ -28,7 +28,7 @@ typedef struct EVDP_EVENT{
/**
/**
* Network Event Dispatcher Initialization / Finalization routines
*/
void evdp_init();
@ -40,22 +40,22 @@ void evdp_final();
*
* @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 timeout_ticks max time to wait in ticks (milliseconds)
* @param timeout_ticks max time to wait in ticks (milliseconds)
*
* @Note:
* The function will block until an event has occured on one of the monitored connections
* or the timeout of timeout_ticks has passed by.
* 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.
*/
int32 evdp_wait(EVDP_EVENT *out_fds, int32 max_events, int32 timeout_ticks);
/**
/**
* Applys the given mask on the given connection.
*
*
* @param fd connection identifier
* @param *ep event data pointer for the connection
* @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);
/**
/**
* Adds a connection (listner) to the event notification system.
*
* @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)
* - 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
*
*
* @return success indicator.
*/
*/
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 *ep event data pointr for the connection
*
*
* @note:
*
*
* MONITORS by default: IN, HUP
*
* @return success indicator.
@ -102,11 +102,11 @@ bool evdp_addclient(int32 fd, EVDP_DATA *ep);
* @note:
* Outgoing connection type sockets are getting monitored for connection established
* 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.
* - Additinionally its edge triggered.
*
* @see evdp_outgoingconnection_established
* @see evdp_outgoingconnection_established
*
*
* @return success indicator
@ -114,14 +114,14 @@ bool evdp_addclient(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 *ep event data pointer for the conneciton.
* @note
* @note
* after this call, its handled like a normal "client" connection (incomming)
*
*
* @rturn success indicator
*/
bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep);
@ -134,19 +134,19 @@ bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep);
*
* @note:
* the connection must be already added (as client or listener)
*
*
*
* @return success indicator
*/
bool evdp_writable_add(int32 fd, EVDP_DATA *ep);
/**
/**
* Removes the connection from writable notification monitoring
*
* @param fd connection identifier
* @param *ep event data pointr for the connection
*
*/
*/
void evdp_writable_remove(int32 fd, EVDP_DATA *ep);
/**
@ -157,7 +157,7 @@ void evdp_writable_remove(int32 fd, EVDP_DATA *ep);
*
*
* @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.
*
*/

View File

@ -1,5 +1,5 @@
//
// Event Dispatcher Abstraction for EPOLL
// Event Dispatcher Abstraction for EPOLL
//
// 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;
void evdp_init(){
epoll_fd = epoll_create( EPOLL_MAX_PER_CYCLE );
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);
}
}//end: evdp_init()
void evdp_final(){
if(epoll_fd != -1){
close(epoll_fd);
epoll_fd = -1;
}
}//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];
register struct epoll_event *ev;
register int nfds, n;
if(max_events > EPOLL_MAX_PER_CYCLE)
max_events = EPOLL_MAX_PER_CYCLE;
nfds = epoll_wait( epoll_fd, l_events, max_events, timeout_ticks);
if(nfds == -1){
// @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));
exit(1); //..
}
// Loop thru all events and copy it to the local ra evdp_event.. struct.
for(n = 0; n < nfds; n++){
ev = &l_events[n];
out_fds->fd = ev->data.fd;
out_fds->events = 0; // clear
if(ev->events & EPOLLHUP)
out_fds->events |= EVDP_EVENT_HUP;
if(ev->events & EPOLLIN)
out_fds->events |= EVDP_EVENT_IN;
if(ev->events & EPOLLOUT)
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()
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()
bool evdp_addlistener(int32 fd, EVDP_DATA *ep){
ep->ev_data.events = EPOLLET|EPOLLIN;
ep->ev_data.data.fd = fd;
// No check here for 'added ?'
// 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.data.fd = -1;
return false;
}
}
ep->ev_added = true;
return true;
}//end: evdp_addlistener()
bool evdp_addclient(int32 fd, EVDP_DATA *ep){
ep->ev_data.events = EPOLLIN | EPOLLHUP;
ep->ev_data.data.fd = fd;
// No check for "added?" here,
// this function only gets called upon accpept.
//
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));
ep->ev_data.events = 0;
ep->ev_data.data.fd = -1;
return false;
}
ep->ev_added = true;
return true;
}//end: evdp_addclient()
bool evdp_addconnecting(int32 fd, EVDP_DATA *ep){
ep->ev_data.events = EPOLLET | EPOLLOUT | EPOLLHUP;
ep->ev_data.data.fd = fd;
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));
ep->ev_data.events = 0;
ep->ev_data.data.fd = -1;
ep->ev_data.data.fd = -1;
}
ep->ev_added = true;
return true;
@ -155,36 +155,36 @@ bool evdp_addconnecting(int32 fd, EVDP_DATA *ep){
bool evdp_outgoingconnection_established(int32 fd, EVDP_DATA *ep){
int32 saved_mask;
if(ep->ev_added != true){
// !
// !
ShowError("evdp [EPOLL]: evdp_outgoingconnection_established fd #%u is not added to event dispatcher! invalid call.\n", fd);
return false;
}
saved_mask = ep->ev_data.events;
ep->ev_data.events = EPOLLIN | EPOLLHUP;
if( epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ep->ev_data) != 0){
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));
return false;
return false;
}
return true;
}//end: evdp_outgoingconnection_established()
bool evdp_writable_add(int32 fd, EVDP_DATA *ep){
if(ep->ev_added != true){
ShowError("evdp [EPOLL]: evdp_writable_add - tried to add not added fd #%u\n",fd);
return false;
}
if(! (ep->ev_data.events & EPOLLOUT) ){ //
if(! (ep->ev_data.events & EPOLLOUT) ){ //
ep->ev_data.events |= EPOLLOUT;
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));
@ -192,27 +192,27 @@ bool evdp_writable_add(int32 fd, EVDP_DATA *ep){
return false;
}
}
return true;
return true;
}//end: evdp_writable_add()
void evdp_writable_remove(int32 fd, EVDP_DATA *ep){
if(ep->ev_added != true){
ShowError("evdp [EPOLL]: evdp_writable_remove - tried to remove not added fd #%u\n", fd);
return;
}
if( ep->ev_data.events & EPOLLOUT ){
ep->ev_data.events &= ~EPOLLOUT;
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));
ep->ev_data.events |= EPOLLOUT; // add back to local flagmask because of failed syscall.
return;
}
}
}
return;
return;
}//end: evdp_writable_remove()

View File

@ -13,7 +13,7 @@
#if defined(MEMWATCH)
# include <string.h>
# include <string.h>
# include "memwatch.h"
# define MALLOC(n,file,line,func) mwMalloc((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);
return NULL;
}
if(size == 0) {
return NULL;
}
@ -375,7 +375,7 @@ void _mfree(void *ptr, const char *file, int line, const char *func )
struct unit_head *head;
if (ptr == NULL)
return;
return;
head = (struct unit_head *)((char *)ptr - sizeof(struct unit_head) + sizeof(long));
if(head->size == 0) {

View File

@ -53,7 +53,7 @@ struct ra_align(16) node{
struct pool_segment{
mempool pool; // pool, this segment belongs to
struct pool_segment *next;
int64 num_nodes_total;
int64 num_nodes_total;
int64 num_bytes;
};
@ -64,7 +64,7 @@ struct mempool{
uint64 elem_size;
uint64 elem_realloc_step;
int64 elem_realloc_thresh;
// Callbacks that get called for every node that gets allocated
// Example usage: initialization of mutex/lock for each node.
memPoolOnNodeAllocationProc onalloc;
@ -73,19 +73,19 @@ struct mempool{
// Locks
SPIN_LOCK segmentLock;
SPIN_LOCK nodeLock;
// Internal
// Internal
struct pool_segment *segments;
struct node *free_list;
volatile int64 num_nodes_total;
volatile int64 num_nodes_free;
volatile int64 num_segments;
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)
// 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 ..
///
///
// Implementation:
//
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){
mempool p;
while(1){
if(l_async_terminate > 0)
break;
EnterSpinLock(&l_mempoolListLock);
for(p = l_mempoolList; p != NULL; p = p->next){
if(p->num_nodes_free < p->elem_realloc_thresh){
// add new segment.
segment_allocate_add(p, p->elem_realloc_step);
// increase stats counter
InterlockedIncrement64(&p->num_realloc_events);
}
}
LeaveSpinLock(&l_mempoolListLock);
ramutex_lock( l_async_lock );
racond_wait( l_async_cond, l_async_lock, -1 );
ramutex_unlock( l_async_lock );
}
return NULL;
}//end: mempool_async_allocator()
@ -142,12 +142,12 @@ void mempool_init(){
if( rand()%2 + 1 )
return;
if(sizeof(struct node)%16 != 0 ){
ShowFatalError("mempool_init: struct node alignment failure. %u != multiple of 16\n", sizeof(struct node));
exit(EXIT_FAILURE);
}
// Global List start
InitializeSpinLock(&l_mempoolListLock);
l_mempoolList = NULL;
@ -168,23 +168,23 @@ void mempool_init(){
void mempool_final(){
mempool p, pn;
if( rand()%2 + 1 )
return;
ShowStatus("Mempool: Terminating async. allocation worker and remaining pools.\n");
// Terminate worker / wait until its terminated.
InterlockedIncrement(&l_async_terminate);
racond_signal(l_async_cond);
rathread_wait(l_async_thread, NULL);
// Destroy cond var and mutex.
racond_destroy( l_async_cond );
ramutex_destroy( l_async_lock );
// 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.)
//
EnterSpinLock(&l_mempoolListLock);
@ -192,7 +192,7 @@ void mempool_final(){
while(1){
if(p == NULL)
break;
pn = p->next;
ShowWarning("Mempool [%s] was not properly destroyed - forcing destroy.\n", p->name);
@ -201,28 +201,28 @@ void mempool_final(){
p = pn;
}
LeaveSpinLock(&l_mempoolListLock);
}//end: mempool_final()
static void segment_allocate_add(mempool p, uint64 count){
// Required Memory:
// sz( segment )
// sz( segment )
// count * sz( real_node_size )
//
//
// where real node size is:
// ALIGN_TO_16( sz( node ) ) + p->elem_size
// so the nodes usable address is nodebase + ALIGN_TO_16(sz(node))
// ALIGN_TO_16( sz( node ) ) + p->elem_size
// so the nodes usable address is nodebase + ALIGN_TO_16(sz(node))
//
size_t total_sz;
struct pool_segment *seg = NULL;
struct node *nodeList = NULL;
struct node *node = NULL;
char *ptr = NULL;
char *ptr = NULL;
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) ) ;
#ifdef MEMPOOL_DEBUG
@ -234,7 +234,7 @@ static void segment_allocate_add(mempool p, uint64 count){
while(1){
ptr = (char*)aMalloc(total_sz);
if(ptr != NULL) break;
i++; // increase failcount.
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);
@ -244,29 +244,29 @@ static void segment_allocate_add(mempool p, uint64 count){
sleep(1);
#endif
}else{
rathread_yield(); /// allow/force vuln. ctxswitch
rathread_yield(); /// allow/force vuln. ctxswitch
}
}//endwhile: allocation spinloop.
// Clear Memory.
memset(ptr, 0x00, total_sz);
// Initialize segment struct.
seg = (struct pool_segment*)ptr;
ptr += ALIGN_TO_16(sizeof(struct pool_segment));
seg->pool = p;
seg->num_nodes_total = count;
seg->num_bytes = total_sz;
// Initialze nodes!
nodeList = NULL;
// Initialze nodes!
nodeList = NULL;
for(i = 0; i < count; i++){
node = (struct node*)ptr;
ptr += sizeof(struct node);
ptr += p->elem_size;
node->segment = seg;
#ifdef MEMPOOLASSERT
node->used = false;
@ -277,16 +277,16 @@ static void segment_allocate_add(mempool p, uint64 count){
node->next = nodeList;
nodeList = node;
}
}
// Link in Segment.
EnterSpinLock(&p->segmentLock);
seg->next = p->segments;
p->segments = seg;
LeaveSpinLock(&p->segmentLock);
// Link in Nodes
EnterSpinLock(&p->nodeLock);
nodeList->next = p->free_list;
@ -299,7 +299,7 @@ static void segment_allocate_add(mempool p, uint64 count){
InterlockedExchangeAdd64(&p->num_nodes_free, count);
InterlockedIncrement64(&p->num_segments);
InterlockedExchangeAdd64(&p->num_bytes_total, total_sz);
}//end: segment_allocate_add()
@ -313,20 +313,20 @@ mempool mempool_create(const char *name,
uint64 realloc_thresh;
mempool pool;
pool = (mempool)aCalloc( 1, sizeof(struct mempool) );
if(pool == NULL){
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.
if(initial_count < 50)
initial_count = 50;
if(realloc_count < 50)
realloc_count = 50;
// 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)
realloc_thresh = 10;
@ -337,7 +337,7 @@ mempool mempool_create(const char *name,
pool->elem_realloc_thresh = realloc_thresh;
pool->onalloc = onNodeAlloc;
pool->ondealloc = onNodeDealloc;
InitializeSpinLock(&pool->segmentLock);
InitializeSpinLock(&pool->nodeLock);
@ -348,15 +348,15 @@ mempool mempool_create(const char *name,
pool->num_bytes_total = 0;
pool->peak_nodes_used = 0;
pool->num_realloc_events = 0;
//
#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);
#endif
// Allocate first segment directly :)
// Allocate first segment directly :)
segment_allocate_add(pool, initial_count);
// Add Pool to the global pool list
EnterSpinLock(&l_mempoolListLock);
@ -364,8 +364,8 @@ mempool mempool_create(const char *name,
l_mempoolList = pool;
LeaveSpinLock(&l_mempoolListLock);
return pool;
return pool;
}//end: mempool_create()
@ -379,7 +379,7 @@ void mempool_destroy(mempool p){
#ifdef MEMPOOL_DEBUG
ShowDebug("Mempool [%s] Destroy\n", p->name);
#endif
// Unlink from global list.
EnterSpinLock(&l_mempoolListLock);
piter = l_mempoolList;
@ -387,11 +387,11 @@ void mempool_destroy(mempool p){
while(1){
if(piter == NULL)
break;
if(piter == p){
// unlink from list,
//
//
if(pprev == l_mempoolList){
// this (p) is list begin. so set next as head.
l_mempoolList = p->next;
@ -401,15 +401,15 @@ void mempool_destroy(mempool p){
}
break;
}
pprev = piter;
pprev = piter;
piter = piter->next;
}
p->next = NULL;
LeaveSpinLock(&l_mempoolListLock);
// Get both locks.
EnterSpinLock(&p->segmentLock);
EnterSpinLock(&p->nodeLock);
@ -417,16 +417,16 @@ void mempool_destroy(mempool p){
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) );
// Free All Segments (this will also free all nodes)
// The segment pointer is the base pointer to the whole segment.
seg = p->segments;
while(1){
if(seg == NULL)
break;
segnext = seg->next;
// ..
if(p->ondealloc != NULL){
// walk over the segment, and call dealloc callback!
@ -442,26 +442,26 @@ void mempool_destroy(mempool p){
continue;
}
#endif
p->ondealloc( NODE_TO_DATA(niter) );
}
}//endif: ondealloc callback?
// simple ..
aFree(seg);
seg = segnext;
}
// Clear node ptr
// Clear node ptr
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_segments, 0);
InterlockedExchange64(&p->num_bytes_total, 0);
LeaveSpinLock(&p->nodeLock);
LeaveSpinLock(&p->segmentLock);
@ -475,34 +475,34 @@ void mempool_destroy(mempool p){
void *mempool_node_get(mempool p){
struct node *node;
int64 num_used;
if(p->num_nodes_free < p->elem_realloc_thresh)
racond_signal(l_async_cond);
while(1){
EnterSpinLock(&p->nodeLock);
node = p->free_list;
if(node != NULL)
p->free_list = node->next;
LeaveSpinLock(&p->nodeLock);
if(node != NULL)
break;
rathread_yield();
}
InterlockedDecrement64(&p->num_nodes_free);
// Update peak value
num_used = (p->num_nodes_total - p->num_nodes_free);
if(num_used > p->peak_nodes_used){
InterlockedExchange64(&p->peak_nodes_used, num_used);
}
#ifdef MEMPOOLASSERT
node->used = true;
#endif
@ -513,12 +513,12 @@ void *mempool_node_get(mempool p){
void mempool_node_put(mempool p, void *data){
struct node *node;
node = DATA_TO_NODE(data);
#ifdef MEMPOOLASSERT
if(node->magic != NODE_MAGIC){
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;
}
}
// reset used flag.
node->used = false;
#endif
//
//
EnterSpinLock(&p->nodeLock);
node->next = p->free_list;
p->free_list = node;
LeaveSpinLock(&p->nodeLock);
InterlockedIncrement64(&p->num_nodes_free);
}//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 stats;
// initialize all with zeros
memset(&stats, 0x00, sizeof(mempool_stats));
stats.num_nodes_total = pool->num_nodes_total;
stats.num_nodes_free = pool->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
// 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;
}//end: mempool_get_stats()

View File

@ -12,33 +12,33 @@ typedef struct mempool_stats{
int64 num_nodes_total;
int64 num_nodes_free;
int64 num_nodes_used;
int64 num_segments;
int64 num_realloc_events;
int64 peak_nodes_used;
int64 num_bytes_total;
} mempool_stats;
//
//
void mempool_init();
void mempool_final();
/**
/**
* Creates a new Mempool
*
* @param name - Name of the pool (used for debug / error messages)
* @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 onNodeAlloc - Node Allocation callback (see @note!)
* @param onNodeDealloc - Node Deallocation callback (see @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 )
* you can use this callbacks for example to initlaize a mutex or somethingelse
* you definitly need during runtime
@ -49,14 +49,14 @@ mempool mempool_create(const char *name,
uint64 elem_size,
uint64 initial_count,
uint64 realloc_count,
memPoolOnNodeAllocationProc onNodeAlloc,
memPoolOnNodeDeallocationProc onNodeDealloc);
/**
* Destroys a Mempool
*
*
* @param pool - the mempool to destroy
*
* @note:
@ -68,7 +68,7 @@ void mempool_destroy(mempool pool);
/**
* Gets a new / empty node from the given mempool.
*
*
* @param pool - the pool to get an empty node from.
*
* @return Address of empty Node
@ -80,12 +80,12 @@ void *mempool_node_get(mempool pool);
* Returns the given node to the given mempool
*
* @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);
/**
/**
* Returns Statistics for the given mempool
*
* @param pool - the pool to get thats for

View File

@ -52,7 +52,7 @@
#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 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]
* 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

View File

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

View File

@ -1,5 +1,5 @@
// 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_
#define _rA_MUTEX_H_
@ -9,36 +9,36 @@ typedef struct ramutex *ramutex; // Mutex
typedef struct racond *racond; // Condition Var
/**
* Creates a Mutex
* Creates a Mutex
*
* @return not NULL
*/
ramutex ramutex_create();
/**
/**
* Destroys a Mutex
*
*
* @param m - the mutex to destroy
*/
void ramutex_destroy( ramutex m );
/**
/**
* Gets a lock
*
* @param m - the mutex to lock
*/
void ramutex_lock( ramutex m);
/**
/**
* Trys to get the Lock
*
*
* @param m - the mutex try to lock
*
*
* @return boolean (true = got the lock)
*/
bool ramutex_trylock( ramutex m );
/**
/**
* Unlocks a mutex
*
* @param m - the mutex to unlock
@ -46,14 +46,14 @@ bool ramutex_trylock( ramutex m );
void ramutex_unlock( ramutex m);
/**
/**
* Creates a Condition variable
*
* @return not NULL
*/
racond racond_create();
/**
/**
* Destroy a Condition variable
*
* @param c - the condition varaible to destroy
@ -62,14 +62,14 @@ void racond_destroy( racond c );
/**
* 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 timeout_ticks - timeout in ticks ( -1 = INFINITE )
*/
void racond_wait( racond c, ramutex m, sysint timeout_ticks);
/**
/**
* Sets the given condition var to 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 );
/**
/**
* Sets notifys all waiting threads thats signalled.
* @param c - condition var to set in signalled state
*
*
* @note:
* All Waiters getting notified.
*/
*/
void racond_broadcast( racond c );

View File

@ -11,10 +11,10 @@
//
//
//
// Buffers are available in the following sizes:
// 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];
raconf conf;
sysint i;
// Initialize Statistic counters:
l_nEmergencyAllocations = 0;
// Set localsection name according to running serverype.
switch(SERVER_TYPE){
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;
default: strcpy(localsection, "unsupported_type"); break;
}
conf = raconf_parse("conf/network.conf");
if(conf == NULL){
ShowFatalError("Failed to Parse required Configuration (conf/network.conf)");
exit(EXIT_FAILURE);
}
// Get Values from config file
l_nPools = (sysint)raconf_getintEx(conf, localsection, "netbuffer", "num", 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);
}
}
// Allocate arrays.
l_poolElemSize = (sysint*)aCalloc( l_nPools, sizeof(sysint) );
l_pool = (mempool*)aCalloc( l_nPools, sizeof(mempool) );
for(i = 0; i < l_nPools; i++){
int64 num_prealloc, num_realloc;
char key[32];
sprintf(key, "pool_%u_size", (uint32)i+1);
l_poolElemSize[i] = (sysint)raconf_getintEx(conf, localsection, "netbuffer", key, 4096);
if(l_poolElemSize[i] < 32){
ShowWarning("Netbuffer (network.conf) failure - minimum allowed buffer size is 32 byte) - fixed.\n");
l_poolElemSize[i] = 32;
}
sprintf(key, "pool_%u_prealloc", (uint32)i+1);
num_prealloc = raconf_getintEx(conf, localsection, "netbuffer", key, 150);
sprintf(key, "pool_%u_realloc_step", (uint32)i+1);
num_realloc = raconf_getintEx(conf, localsection, "netbuffer", key, 100);
// Create Pool!
sprintf(key, "Netbuffer %u", (uint32)l_poolElemSize[i]); // name.
// 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);
//
// Size Calculation:
// 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]);
// @leak: clean everything :D
exit(EXIT_FAILURE);
}
}//
}
}//
raconf_destroy(conf);
}//end: netbuffer_init()
@ -106,58 +106,58 @@ void netbuffer_init(){
void netbuffer_final(){
sysint i;
if(l_nPools > 0){
/// .. finalize mempools
for(i = 0; i < l_nPools; 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);
mempool_destroy(l_pool[i]);
}
}
if(l_nEmergencyAllocations > 0){
ShowWarning("Netbuffer: did %u Emergency Allocations, please tune your network.conf!\n", l_nEmergencyAllocations);
l_nEmergencyAllocations = 0;
}
aFree(l_poolElemSize); l_poolElemSize = NULL;
aFree(l_pool); l_pool = NULL;
l_nPools = 0;
}
}//end: netbuffer_final()
netbuf netbuffer_get( sysint sz ){
sysint i;
netbuf nb = NULL;
// Search an appropriate pool
for(i = 0; i < l_nPools; i++){
if(sz <= l_poolElemSize[i]){
// match
nb = (netbuf)mempool_node_get(l_pool[i]);
// match
nb = (netbuf)mempool_node_get(l_pool[i]);
nb->pool = i;
break;
}
}
}
// No Bufferpool found that mets there quirements?.. (thats bad..)
if(nb == NULL){
ShowWarning("Netbuffer: get(%u): => no appropriate pool found - emergency allocation required.\n", sz);
ShowWarning("Please reconfigure your network.conf!");
InterlockedIncrement(&l_nEmergencyAllocations);
// .. better to check (netbuf struct provides 32 byte bufferspace itself.
if(sz < 32) sz = 32;
// allocate memory using malloc ..
// allocate memory using malloc ..
while(1){
nb = (netbuf) aMalloc( (sizeof(struct netbuf) + sz - 32) );
if(nb != NULL){
@ -165,42 +165,42 @@ netbuf netbuffer_get( sysint sz ){
nb->pool = -1; // emergency alloc.
break;
}
rathread_yield();
}// spin allocation.
}
nb->refcnt = 1; // Initial refcount is 1
return nb;
return nb;
}//end: netbuffer_get()
void netbuffer_put( netbuf nb ){
// Decrement reference counter, if > 0 do nothing :)
if( InterlockedDecrement(&nb->refcnt) > 0 )
return;
// Is this buffer an emergency allocated buffer?
if(nb->pool == -1){
aFree(nb);
aFree(nb);
return;
}
// Otherwise its a normal mempool based buffer
// return it to the according mempool:
mempool_node_put( l_pool[nb->pool], nb);
}//end: netbuffer_put()
void netbuffer_incref( netbuf nb ){
InterlockedIncrement(&nb->refcnt);
}//end: netbuf_incref()

View File

@ -8,11 +8,11 @@
typedef struct netbuf{
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.
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
// and can be reused.
@ -20,7 +20,7 @@ typedef struct netbuf{
// Used only for Reading (recv job)
// write cases are using the sessions local datapos member due to
// shared write buffer support.
int32 dataLen; // read buffer case:
// The length expected to read to.
// when this->dataPos == dateLen, read job has been completed.
@ -56,16 +56,16 @@ void netbuffer_final();
netbuf netbuffer_get( sysint sz );
/**
/**
* 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 );
/**
* Increases the Refcount on the given buffer
/**
* Increases the Refcount on the given buffer
* (used for areasends .. etc)
*
*/

View File

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

View File

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

View File

@ -17,10 +17,10 @@ int nullpo_chk_f(const char *file, int line, const char *func, const void *targe
const char *fmt, ...)
{
va_list ap;
if (target != NULL)
return 0;
va_start(ap, fmt);
nullpo_info_core(file, line, func, fmt, 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)
*--------------------------------------*/
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, ...)
{
va_list ap;
va_start(ap, fmt);
nullpo_info_core(file, line, func, fmt, 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){
if (file == NULL)
file = "??";
func =
func == NULL ? "unknown":
func[0] == '\0' ? "unknown":
func;
ShowMessage("--- nullpo info --------------------------------------------\n");
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)
*--------------------------------------*/
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)
{
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')
{
vprintf(fmt, ap);
// Check whether the new line at the end
if (fmt[strlen(fmt)-1] != '\n')
ShowMessage("\n");

View File

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

View File

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

View File

@ -7,8 +7,8 @@
#include "cbasetypes.h"
// rAthena generic configuration file parser
//
// Config file Syntax is athena style
//
// Config file Syntax is athena style
// extended with ini style support (including sections)
//
// Comments are started with // or ; (ini style)
@ -17,9 +17,9 @@
typedef struct raconf *raconf;
/**
/**
* Parses a rAthna Configuration file
*
*
* @param file_name path to the file to parse
*
* @returns not NULL incase of success
@ -27,7 +27,7 @@ typedef struct raconf *raconf;
raconf raconf_parse(const char *file_name);
/**
/**
* Frees a Handle received from raconf_parse
*
* @param rc - the handle to free
@ -35,17 +35,17 @@ raconf raconf_parse(const char *file_name);
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);
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);
/**
* 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.
*
*/

View File

@ -99,7 +99,7 @@ char console_log_filepath[32] = "./log/unknown.log";
// ansi compatible printf with control sequence parser for windows
// 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[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)
//
// \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.
//
// \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.
//
// \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.
//
// \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.
//
// \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.
//
// \033[#;#H - Cursor Position (CUP)
// 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:
// 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 upper-left corner of the screen (line 1, column 1).
//
// \033[#;#f - Horizontal & Vertical Position
// (same as \033[#;#H)
//
// \033[s - Save Cursor Position (SCP)
// The current cursor position is saved.
// The current cursor position is saved.
//
// \033[u - Restore cursor position (RCP)
// 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);
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) )
WriteFile(handle,q, 1, &written, 0);
p=q+1; //and start searching again
@ -241,7 +241,7 @@ int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
q=q+2;
for(;;)
{
if( ISDIGIT(*q) )
if( ISDIGIT(*q) )
{ // add number to number array, only accept 2digits, shift out the rest
// so // \033[123456789m will become \033[89m
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)
{ // Number of chars on screen.
cnt = info.dwSize.X * info.dwSize.Y;
SetConsoleCursorPosition(handle, origin);
SetConsoleCursorPosition(handle, origin);
}
else// 0 and default
{ // number of chars from cursor to end
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);
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' )
{ // \033[#;#H - Cursor Position (CUP)
// \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
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;
@ -494,7 +494,7 @@ int VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
--q;
}
// skip the sequencer and search again
p = q+1;
p = q+1;
break;
}// end while
}
@ -550,7 +550,7 @@ int VFPRINTF(FILE *file, const char *fmt, va_list argptr)
{ // find the escape character
fprintf(file, "%.*s", (int)(q-p), p); // write up to the escape
if( q[1]!='[' )
{ // write the escape char (whatever purpose it has)
{ // write the escape char (whatever purpose it has)
fprintf(file, "%.*s", 1, q);
p=q+1; //and start searching again
}
@ -563,7 +563,7 @@ int VFPRINTF(FILE *file, const char *fmt, va_list argptr)
q=q+2;
while(1)
{
if( ISDIGIT(*q) )
if( ISDIGIT(*q) )
{
++q;
// and next character
@ -632,7 +632,7 @@ int VFPRINTF(FILE *file, const char *fmt, va_list argptr)
--q;
}
// skip the sequencer and search again
p = q+1;
p = q+1;
break;
}// 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)
FILE *fp;
#endif
if (!string || *string == '\0') {
ShowError("Empty string passed to _vShowMessage().\n");
return 1;

View File

@ -867,7 +867,7 @@ int do_sockets(int next)
if (last_tick != socket_data_last_tick)
{
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.);
#ifdef _WIN32
SetConsoleTitle(buf);
@ -1244,7 +1244,7 @@ int socket_getips(uint32* ips, int max)
#ifdef WIN32
{
char fullhost[255];
char fullhost[255];
// XXX This should look up the local IP addresses in the registry
// instead of calling gethostbyname. However, the way IP addresses

View File

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

View File

@ -94,7 +94,7 @@ static int Sql_P_Keepalive(Sql* self);
* @param host : hostname
* @param port : port
* @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)
{

View File

@ -210,10 +210,10 @@ void Sql_Free(Sql* self);
///////////////////////////////////////////////////////////////////////////////
// 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.
// 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.
//
// example queries with parameters:
@ -298,7 +298,7 @@ size_t SqlStmt_NumColumns(SqlStmt* self);
/// Binds the result of a column to a buffer.
/// 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).
///
/// @return SQL_SUCCESS or SQL_ERROR

View File

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

View File

@ -1,7 +1,7 @@
// Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#pragma once
#pragma once
#ifndef _rA_THREAD_H_
#define _rA_THREAD_H_
@ -13,7 +13,7 @@ typedef void* (*rAthreadProc)(void*);
typedef enum RATHREAD_PRIO {
RAT_PRIO_LOW = 0,
RAT_PRIO_NORMAL,
RAT_PRIO_HIGH
RAT_PRIO_HIGH
} RATHREAD_PRIO;
@ -22,18 +22,18 @@ typedef enum RATHREAD_PRIO {
*
* @param entyPoint - entryProc,
* @param param - general purpose parameter, would be given as parameter to the thread's entrypoint.
*
*
* @return not NULL if success
*/
rAthread rathread_create( rAthreadProc entryPoint, void *param );
/**
/**
* Creates a new Thread (with more creation options)
*
* @param entyPoint - entryProc,
* @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..
*
* @return not NULL if success
@ -44,29 +44,29 @@ rAthread rathread_createEx( rAthreadProc entryPoint, void *param, size_t szSta
/**
* 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.
*/
void rathread_destroy ( rAthread handle );
/**
/**
* Returns the thread handle of the thread calling this function
*
*
* @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
*/
rAthread rathread_self( );
/**
* Returns own thrad id (TID)
* Returns own thrad id (TID)
*
* @note this is an unique identifier for the calling thread, and
* depends on platfrom / compiler, and may not be the systems Thread ID!
* @note this is an unique identifier for the calling thread, and
* depends on platfrom / compiler, and may not be the systems Thread ID!
*
* @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 out_Exitcode - [OPTIONAL] - if given => Exitcode (value) of the given thread - if it's terminated
*
*
* @return true - if the given thread has been terminated.
*/
bool rathread_wait( rAthread handle, void* *out_exitCode );
/**
/**
* Sets the given PRIORITY @ OS Task Scheduler
*
*
* @param handle - thread to set prio for
* @param rio - the priority (RAT_PRIO_LOW ... )
*/
void rathread_prio_set( rAthread handle, RATHREAD_PRIO prio );
/**
/**
* Gets the current Prio of the given trhead
*
* @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
*
*
* @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.
*/
void rathread_yield();

View File

@ -427,7 +427,7 @@ void split_time(int timein, int* year, int* month, int* day, int* hour, int* min
const int factor_min = 60;
const int factor_hour = factor_min*60;
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)
*year = timein/factor_year;
@ -459,7 +459,7 @@ double solve_time(char* modif_p) {
time_t now = time(NULL);
time_t then = now;
then_tm = *localtime(&then);
nullpo_retr(0,modif_p);
while (modif_p[0] != '\0') {

View File

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

View File

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