summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfcolin2006-04-19 08:28:14 +0000
committerfcolin2006-04-19 08:28:14 +0000
commit6bf117656574521545694a1a4e5169755077631e (patch)
treef18c164c217e2279781a3af9851b644da97dfba1
parentca9eddefaec96a20b88b9aba25a9384037317c91 (diff)
downloadivy-c-6bf117656574521545694a1a4e5169755077631e.zip
ivy-c-6bf117656574521545694a1a4e5169755077631e.tar.gz
ivy-c-6bf117656574521545694a1a4e5169755077631e.tar.bz2
ivy-c-6bf117656574521545694a1a4e5169755077631e.tar.xz
correction de probleme potentiel en multithread ( Ada rejeu )
ajout d'un warning en cas de client bloquant si la varaiable d'env IVY_DEBUG_SEND est positionne
-rw-r--r--src/Makefile12
-rwxr-xr-xsrc/Makefile.win329
-rw-r--r--src/ivy.c101
-rw-r--r--src/ivy.h4
-rw-r--r--src/ivyloop.c16
-rw-r--r--src/ivyloop.h20
-rwxr-xr-xsrc/ivyperf.c7
-rw-r--r--src/ivyprobe.c2
-rw-r--r--src/ivysocket.c154
-rw-r--r--src/ivysocket.h7
-rw-r--r--src/list.h18
-rw-r--r--src/timer.c22
12 files changed, 191 insertions, 181 deletions
diff --git a/src/Makefile b/src/Makefile
index 778da73..fdd3e28 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -69,12 +69,12 @@ CHANNEL = -DTCL_CHANNEL_INTEGRATION
CFLAGS = -g -Wall
-OBJ = ivyloop.o timer.o ivysocket.o ivy.o
-GOBJ = ivyloop.o timer.o ivysocket.o givy.o
-XTOBJ = ivyxtloop.o ivysocket.o ivy.o
-GLIBOBJ = ivyglibloop.o ivysocket.o ivy.o
-GLUTOBJ = ivyglutloop.o ivysocket.o ivy.o
-TCLOBJ = ivytcl.o timer.o ivysocket.o givy.o
+OBJ = ivyloop.o timer.o ivysocket.o ivy.o ivybuffer.o
+GOBJ = ivyloop.o timer.o ivysocket.o givy.o ivybuffer.o
+XTOBJ = ivyxtloop.o ivysocket.o ivy.o ivybuffer.o
+GLIBOBJ = ivyglibloop.o ivysocket.o ivy.o ivybuffer.o
+GLUTOBJ = ivyglutloop.o ivysocket.o ivy.o ivybuffer.o
+TCLOBJ = ivytcl.o timer.o ivysocket.o givy.o ivybuffer.o
# WINDOWS add ivyloop.o if TCL_CHANNEL_INTEGRATION is not set
TARGETS = ivyprobe ivyperf ivyglibprobe ivyxtprobe
diff --git a/src/Makefile.win32 b/src/Makefile.win32
index 52f024e..f7aec5a 100755
--- a/src/Makefile.win32
+++ b/src/Makefile.win32
@@ -19,8 +19,11 @@
MAJOR=3
MINOR=8
-PCREINC = -I "C:\Program Files\GnuWin32\include" #`pcre-config --cflags`
-PCRELIB = "C:\Program Files\GnuWin32\lib\libpcre.lib" #`pcre-config --libs`
+PCREINC = -I "C:\Documents and Settings\fcolin\My Documents\Visual Studio 2005\Projects\pcre-6.4"
+PCRELIB = "C:\Documents and Settings\fcolin\My Documents\Visual Studio 2005\Projects\pcre-6.4\lib\libpcre.lib" #`pcre-config --libs`
+
+#PCREINC = -I "C:\Program Files\GnuWin32\include" #`pcre-config --cflags`
+#PCRELIB = "C:\Program Files\GnuWin32\lib\libpcre.lib" #`pcre-config --libs`
PCRE_OPT = PCRE_CASELESS
REGCOMP_OPT = REG_ICASE
@@ -34,7 +37,7 @@ PCREOBJ =
#CC=gcc
#CFLAGS = -g -Wall
-CFLAGS = -DWIN32 -nologo
+CFLAGS = -DWIN32 -D_CRT_SECURE_NO_DEPRECATE -nologo
#LIBTOOL=ar q # linux and solaris
#LIBTOOL=libtool -static -o
LIBTOOL=lib -nologo /out:
diff --git a/src/ivy.c b/src/ivy.c
index f03a4b1..07e262e 100644
--- a/src/ivy.c
+++ b/src/ivy.c
@@ -38,11 +38,12 @@
#include "ivychannel.h"
#include "ivysocket.h"
#include "list.h"
+#include "ivybuffer.h"
#include "ivy.h"
#define VERSION 3
-#define MAX_MATCHING_ARGS 20
+#define MAX_MATCHING_ARGS 40
#define ARG_START "\002"
#define ARG_END "\003"
@@ -161,9 +162,9 @@ static char * nextArg( char *s, const char *separator )
if ( end == start ) return NULL;
return start;
}
-static void MsgSendTo( Client client, MsgType msgtype, int id, const char *message )
+static int MsgSendTo( Client client, MsgType msgtype, int id, const char *message )
{
- SocketSend( client, "%d %d" ARG_START "%s\n", msgtype, id, message);
+ return SocketSend( client, "%d %d" ARG_START "%s\n", msgtype, id, message);
}
static void IvyCleanup()
@@ -187,11 +188,11 @@ static void IvyCleanup()
#ifdef USE_PCRE_REGEX
static int
-MsgCall (const char *message, MsgSndPtr msg, Client client)
+MsgCall (const char *message, MsgSndPtr msg, IvyClientPtr client)
{
- static char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */
- static int size = 0; /* donc non reentrant !!!! */
- int offset = 0;
+ int waiting = 0;
+ static IvyBuffer buffer = { NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
+ int err;
int ovector[OVECSIZE];
int index;
int rc=pcre_exec(
@@ -207,32 +208,35 @@ MsgCall (const char *message, MsgSndPtr msg, Client client)
#ifdef DEBUG
printf( "Sending message id=%d '%s'\n",msg->id,message);
#endif
+ buffer.offset = 0;
// il faut essayer d'envoyer le message en une seule fois sur la socket
// pour eviter au maximun de passer dans le select plusieur fois par message du protocole Ivy
// pour eviter la latence ( PB de perfo detecte par ivyperf ping roudtrip )
- offset += make_message_var( &buffer, &size, offset, "%d %d" ARG_START ,Msg, msg->id);
+ err = make_message_var( &buffer, "%d %d" ARG_START ,Msg, msg->id);
#ifdef DEBUG
printf( "Send matching args count %ld\n",msg->regexp.re_nsub);
#endif
index=1;
while ( index<rc ) {
- offset += make_message_var( &buffer, &size, offset, "%.*s" ARG_END , ovector[2*index+1]- ovector[2*index],
+ err = make_message_var( &buffer, "%.*s" ARG_END , ovector[2*index+1]- ovector[2*index],
message + ovector[2*index]);
++index;
}
- offset += make_message_var( &buffer, &size, offset, "\n");
- SocketSendRaw(client, buffer , offset);
+ err = make_message_var( &buffer, "\n");
+ waiting = SocketSendRaw(client->client, buffer.data , buffer.offset);
+ if ( waiting )
+ fprintf(stderr, "Ivy: Slow client : %s\n", client->app_name );
return 1;
}
#else /* we don't USE_PCRE_REGEX */
static int
-MsgCall (const char *message, MsgSndPtr msg, Client client)
+MsgCall (const char *message, MsgSndPtr msg, IvyClientPtr client)
{
- static char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */
- static int size = 0; /* donc non reentrant !!!! */
- int offset = 0;
-
+ int waiting = 0;
+ static IvyBuffer buffer = { NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
+ int err;
+
regmatch_t match[MAX_MATCHING_ARGS+1];
#ifdef GNU_REGEXP
regmatch_t* p;
@@ -249,7 +253,8 @@ MsgCall (const char *message, MsgSndPtr msg, Client client)
// il faut essayer d'envoyer le message en une seule fois sur la socket
// pour eviter au maximun de passer dans le select plusieur fois par message du protocole Ivy
// pour eviter la latence ( PB detecte par ivyperf ping roudtrip )
- offset += make_message_var( &buffer, &size, offset, "%d %d" ARG_START ,Msg, msg->id);
+ buffer.offset = 0;
+ err = make_message_var( &buffer, "%d %d" ARG_START ,Msg, msg->id);
#ifdef DEBUG
printf( "Send matching args count %ld\n",msg->regexp.re_nsub);
@@ -258,7 +263,7 @@ MsgCall (const char *message, MsgSndPtr msg, Client client)
#ifdef GNU_REGEXP
p = &match[1];
while ( p->rm_so != -1 ) {
- offset += make_message_var( &buffer, &size, offset, "%.*s" ARG_END , p->rm_eo - p->rm_so,
+ err = make_message_var( &buffer, "%.*s" ARG_END , p->rm_eo - p->rm_so,
message + p->rm_so);
++p;
}
@@ -270,10 +275,10 @@ MsgCall (const char *message, MsgSndPtr msg, Client client)
printf ("Send matching arg%d %.*s\n",i,(int)(match[i].rm_eo - match[i].rm_so),
message + match[i].rm_so);
#endif
- offset += make_message_var( &buffer, &size, offset, "%.*s" ARG_END ,(int)(match[i].rm_eo - match[i].rm_so),
+ buffer.offset += make_message_var( &buffer, "%.*s" ARG_END ,(int)(match[i].rm_eo - match[i].rm_so),
message + match[i].rm_so);
} else {
- offset += make_message_var( &buffer, &size, offset, ARG_END );
+ buffer.offset += make_message_var( &buffer, ARG_END );
#ifdef DEBUG
printf( "Send matching arg%d VIDE\n",i);
#endif //DEBUG
@@ -281,8 +286,8 @@ MsgCall (const char *message, MsgSndPtr msg, Client client)
}
#endif
- offset += make_message_var( &buffer, &size, offset, "\n");
- SocketSendRaw(client, buffer , offset);
+ err = make_message_var( &buffer,"\n");
+ SocketSendRaw(client->client, buffer.data , buffer.offset);
return 1;
}
#endif /* USE_PCRE_REGEX */
@@ -294,7 +299,7 @@ ClientCall (IvyClientPtr clnt, const char *message)
int match_count = 0;
/* recherche dans la liste des requetes recues de ce client */
IVY_LIST_EACH (clnt->msg_send, msg) {
- match_count+= MsgCall (message, msg, clnt->client);
+ match_count+= MsgCall (message, msg, clnt);
}
return match_count;
}
@@ -401,9 +406,7 @@ static void Receive( Client client, void *data, char *line )
reg = regcomp(&regexp, arg, REGCOMP_OPT|REG_EXTENDED);
if ( reg == 0 )
{
- IVY_LIST_ADD( clnt->msg_send, snd )
- if ( snd )
- {
+ IVY_LIST_ADD_START( clnt->msg_send, snd )
snd->id = id;
snd->str_regexp = strdup( arg );
snd->regexp = regexp;
@@ -411,7 +414,7 @@ static void Receive( Client client, void *data, char *line )
{
(*application_bind_callback)( clnt, application_bind_data, id, snd->str_regexp, IvyAddBind );
}
- }
+ IVY_LIST_ADD_END( clnt->msg_send, snd )
}
else
{
@@ -424,9 +427,7 @@ static void Receive( Client client, void *data, char *line )
regexp = pcre_compile(arg, PCRE_OPT,&errbuf,&erroffset,NULL);
if ( regexp != NULL )
{
- IVY_LIST_ADD( clnt->msg_send, snd )
- if ( snd )
- {
+ IVY_LIST_ADD_START( clnt->msg_send, snd )
snd->id = id;
snd->str_regexp = strdup( arg );
snd->regexp = regexp;
@@ -440,7 +441,8 @@ static void Receive( Client client, void *data, char *line )
{
(*application_bind_callback)( clnt, application_bind_data, id, snd->str_regexp, IvyAddBind );
}
- }
+ IVY_LIST_ADD_END( clnt->msg_send, snd )
+
}
else
{
@@ -564,9 +566,8 @@ static IvyClientPtr SendService( Client client )
{
IvyClientPtr clnt;
MsgRcvPtr msg;
- IVY_LIST_ADD( clients, clnt )
- if ( clnt )
- {
+ IVY_LIST_ADD_START( clients, clnt )
+
clnt->msg_send = 0;
clnt->client = client;
clnt->app_name = strdup("Unknown");
@@ -577,7 +578,8 @@ static IvyClientPtr SendService( Client client )
MsgSendTo( client, AddRegexp,msg->id,msg->regexp);
}
MsgSendTo( client, EndRegexp, 0, "");
- }
+
+ IVY_LIST_ADD_END( clients, clnt )
return clnt;
}
@@ -837,25 +839,24 @@ IvyUnbindMsg (MsgRcvPtr msg)
MsgRcvPtr
IvyBindMsg (MsgCallback callback, void *user_data, const char *fmt_regex, ... )
{
- static char *buffer = NULL;
- static int size = 0;
+ static IvyBuffer buffer = { NULL, 0, 0};
va_list ap;
static int recv_id = 0;
IvyClientPtr clnt;
MsgRcvPtr msg;
va_start (ap, fmt_regex );
- make_message( &buffer, &size, 0, fmt_regex, ap );
+ buffer.offset = 0;
+ make_message( &buffer, fmt_regex, ap );
va_end (ap );
/* add Msg to the query list */
- IVY_LIST_ADD( msg_recv, msg );
- if (msg) {
+ IVY_LIST_ADD_START( msg_recv, msg )
msg->id = recv_id++;
- msg->regexp = strdup(buffer);
+ msg->regexp = strdup(buffer.data);
msg->callback = callback;
msg->user_data = user_data;
- }
+ IVY_LIST_ADD_END( msg_recv, msg )
/* Send to already connected clients */
/* recherche dans la liste des requetes recues de mes clients */
IVY_LIST_EACH( clients, clnt ) {
@@ -868,17 +869,17 @@ int IvySendMsg(const char *fmt, ...)
{
IvyClientPtr clnt;
int match_count = 0;
- static char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */
- static int size = 0; /* donc non reentrant !!!! */
+ static IvyBuffer buffer = { NULL, 0, 0}; /* Use satic mem to eliminate multiple call to malloc /free */
va_list ap;
va_start( ap, fmt );
- make_message( &buffer, &size, 0, fmt, ap );
+ buffer.offset = 0;
+ make_message( &buffer, fmt, ap );
va_end ( ap );
/* recherche dans la liste des requetes recues de mes clients */
IVY_LIST_EACH (clients, clnt) {
- match_count += ClientCall (clnt, buffer);
+ match_count += ClientCall (clnt, buffer.data);
}
#ifdef DEBUG
if ( match_count == 0 ) printf( "Warning no recipient for %s\n",buffer);
@@ -888,14 +889,14 @@ int IvySendMsg(const char *fmt, ...)
void IvySendError( IvyClientPtr app, int id, const char *fmt, ... )
{
- static char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */
- static int size = 0; /* donc non reentrant !!!! */
+ static IvyBuffer buffer = { NULL, 0, 0}; /* Use satic mem to eliminate multiple call to malloc /free */
va_list ap;
va_start( ap, fmt );
- make_message( &buffer, &size, 0, fmt, ap );
+ buffer.offset = 0;
+ make_message( &buffer, fmt, ap );
va_end ( ap );
- MsgSendTo( app->client, Error, id, buffer);
+ MsgSendTo( app->client, Error, id, buffer.data);
}
void IvyBindDirectMsg( MsgDirectCallback callback, void *user_data)
diff --git a/src/ivy.h b/src/ivy.h
index 1ea319a..9911137 100644
--- a/src/ivy.h
+++ b/src/ivy.h
@@ -65,10 +65,10 @@ void IvyInit(
void *die_data /* user data */
);
- void IvySetBindCallback(
+void IvySetBindCallback(
IvyBindCallback bind_callback,
void *bind_data );
- void IvyDelBindCallback();
+void IvyDelBindCallback();
void IvyStart (const char*);
void IvyStop ();
diff --git a/src/ivyloop.c b/src/ivyloop.c
index 9ccd427..cf121e3 100644
--- a/src/ivyloop.c
+++ b/src/ivyloop.c
@@ -98,17 +98,14 @@ Channel IvyChannelSetUp (HANDLE fd, void *data,
{
Channel channel;
- IVY_LIST_ADD (channels_list, channel);
- if (!channel) {
- fprintf(stderr,"NOK Memory Alloc Error\n");
- exit(0);
- }
+ IVY_LIST_ADD_START (channels_list, channel)
channel->fd = fd;
channel->tobedeleted = 0;
channel->handle_delete = handle_delete;
channel->handle_read = handle_read;
channel->data = data;
-
+ IVY_LIST_ADD_END (channels_list, channel)
+
FD_SET (channel->fd, &open_fds);
return channel;
@@ -165,7 +162,7 @@ void IvyStop (void)
MainLoop = 0;
}
-void IvyMainLoop(void(*hook)(void))
+void IvyMainLoop(void(*BeforeSelect)(void),void(*AfterSelect)(void))
{
fd_set rdset;
@@ -174,10 +171,12 @@ void IvyMainLoop(void(*hook)(void))
while (MainLoop) {
ChannelDefferedDelete();
- if (hook) (*hook)();
+ if (BeforeSelect) (*BeforeSelect)();
rdset = open_fds;
exset = open_fds;
ready = select(64, &rdset, 0, &exset, TimerGetSmallestTimeout());
+ if (AfterSelect) (*AfterSelect)();
+
if (ready < 0 && (errno != EINTR)) {
fprintf (stderr, "select error %d\n",errno);
perror("select");
@@ -187,7 +186,6 @@ void IvyMainLoop(void(*hook)(void))
if (ready > 0) {
IvyChannelHandleExcpt(&exset);
IvyChannelHandleRead(&rdset);
- continue;
}
}
}
diff --git a/src/ivyloop.h b/src/ivyloop.h
index c4af6eb..0696d40 100644
--- a/src/ivyloop.h
+++ b/src/ivyloop.h
@@ -36,9 +36,23 @@ extern "C" {
#define HANDLE int
#endif
-
-
-extern void IvyMainLoop(void(*hook)(void) );
+/*
+Boucle principale d'IVY baseé sur un select
+les fonctions hook et unhook encradre le select
+de la maniere suivante:
+
+ BeforeSelect est appeler avant l'appel system select
+ AfterSelect est appeler avent l'appel system select
+ ces function peuvent utilisées pour depose un verrou dans le cas
+ d'utilisation de la mainloop Ivy dans une thread separe
+
+ BeforeSelect ==> on libere l'acces avant la mise en attente sur le select
+ AfterSelect == > on verrouille l'acces en sortie du select
+
+ !!!! Attention donc l'appel des callbacks ivy se fait avec l'acces verrouille !
+*/
+
+extern void IvyMainLoop(void(*BeforeSelect)(void),void(*AfterSelect)(void) );
extern void IvyChannelInit(void);
diff --git a/src/ivyperf.c b/src/ivyperf.c
index 11e9522..999fb69 100755
--- a/src/ivyperf.c
+++ b/src/ivyperf.c
@@ -76,9 +76,10 @@ void TimerCall(TimerId id, void *user_data, unsigned long delta)
int main(int argc, char *argv[])
{
-
+ long time=200;
/* Mainloop management */
+ if ( argc > 1 ) time = atol( argv[1] );
IvyInit ("IvyPerf", "IvyPerf ready", NULL,NULL,NULL,NULL);
@@ -87,9 +88,9 @@ int main(int argc, char *argv[])
IvyStart (0);
- TimerRepeatAfter (TIMER_LOOP, 200, TimerCall, (void*)1);
+ TimerRepeatAfter (TIMER_LOOP, time, TimerCall, (void*)1);
- IvyMainLoop (0);
+ IvyMainLoop (0,0);
return 0;
}
diff --git a/src/ivyprobe.c b/src/ivyprobe.c
index 10a3b00..4bcc167 100644
--- a/src/ivyprobe.c
+++ b/src/ivyprobe.c
@@ -398,7 +398,7 @@ int main(int argc, char *argv[])
#endif
#ifdef IVYMAINLOOP
- IvyMainLoop (0);
+ IvyMainLoop (0,0);
#endif
return 0;
}
diff --git a/src/ivysocket.c b/src/ivysocket.c
index 1bb9c62..5b2fa93 100644
--- a/src/ivysocket.c
+++ b/src/ivysocket.c
@@ -41,6 +41,7 @@
#include "ivychannel.h"
#include "ivysocket.h"
#include "ivyloop.h"
+#include "ivybuffer.h"
#define BUFFER_SIZE 4096 /* taille buffer initiale on multiple pas deux a chaque realloc */
@@ -63,59 +64,26 @@ struct _client {
SocketInterpretation interpretation;
void (*handle_delete)(Client client, void *data);
char terminator; /* character delimiter of the message */
+ /* Buffer de reception */
long buffer_size;
char *buffer; /* dynamicaly reallocated */
char *ptr;
+ /* user data */
void *data;
};
static Server servers_list = NULL;
static Client clients_list = NULL;
-#ifdef WIN32
-WSADATA WsaData;
+#ifdef DEBUG
+static int debug_send = 1;
+#else
+static int debug_send = 0;
#endif
-// fonction de formtage a la printf d'un buffer avec reallocation dynamique
-int make_message(char ** buffer, int *size, int offset, const char *fmt, va_list ap)
-{
- /* Guess we need no more than BUFFER_INIT_SIZE bytes. */
- int n;
- if ( *size == 0 || *buffer == NULL )
- {
- *size = BUFFER_SIZE;
- *buffer = malloc (BUFFER_SIZE);
- if ( *buffer == NULL )
- return -1;
- }
- while (1) {
- /* Try to print in the allocated space. */
#ifdef WIN32
- n = _vsnprintf (*buffer + offset, *size - offset, fmt, ap);
-#else
- n = vsnprintf (*buffer + offset, *size - offset, fmt, ap);
+WSADATA WsaData;
#endif
- /* If that worked, return the string size. */
- if (n > -1 && n < *size)
- return n;
- /* Else try again with more space. */
- if (n > -1) /* glibc 2.1 */
- *size = n+1; /* precisely what is needed */
- else /* glibc 2.0 */
- *size *= 2; /* twice the old size */
- if ((*buffer = realloc (*buffer, *size)) == NULL)
- return -1;
- }
-}
-int make_message_var(char ** buffer, int *size, int offset, const char *fmt, ... )
-{
- va_list ap;
- int len;
- va_start (ap, fmt );
- len = make_message (buffer,size, offset, fmt, ap );
- va_end (ap );
- return len;
-}
void SocketInit()
{
@@ -124,6 +92,7 @@ void SocketInit()
fprintf (stderr, "Channel management functions not set, exiting.\n");
exit(-1);
}
+ if ( getenv( "IVY_DEBUG_SEND" )) debug_send = 1;
(*channel_init)();
}
@@ -223,13 +192,8 @@ static void HandleServer(Channel channel, HANDLE fd, void *data)
#ifdef DEBUG
printf( "Accepting Connection ret\n");
#endif //DEBUG
- IVY_LIST_ADD (clients_list, client );
- if (!client )
- {
- fprintf(stderr,"NOK Memory Alloc Error\n");
- close (fd );
- exit(0);
- }
+ IVY_LIST_ADD_START (clients_list, client );
+
client->buffer_size = BUFFER_SIZE;
client->buffer = malloc( client->buffer_size );
if (!client->buffer )
@@ -245,6 +209,9 @@ static void HandleServer(Channel channel, HANDLE fd, void *data)
client->ptr = client->buffer;
client->handle_delete = server->handle_delete;
client->data = (*server->create) (client );
+
+ IVY_LIST_ADD_END (clients_list, client );
+
}
Server SocketServer(unsigned short port,
@@ -306,18 +273,15 @@ Server SocketServer(unsigned short port,
};
- IVY_LIST_ADD (servers_list, server );
- if (!server )
- {
- fprintf(stderr,"NOK Memory Alloc Error\n");
- exit(0);
- }
+ IVY_LIST_ADD_START (servers_list, server );
server->fd = fd;
server->channel = (*channel_setup) (fd, server, DeleteServerSocket, HandleServer );
server->create = create;
server->handle_delete = handle_delete;
server->interpretation = interpretation;
server->port = ntohs(local.sin_port);
+ IVY_LIST_ADD_END (servers_list, server );
+
return server;
}
@@ -376,16 +340,45 @@ void SocketClose (Client client )
(*channel_close) (client->channel );
}
-void SocketSendRaw (Client client, char *buffer, int len )
+int SocketSendRaw (Client client, char *buffer, int len )
{
int err;
+ int waiting= 0;
if (!client)
- return;
+ return waiting;
+
+ if ( debug_send )
+ {
+ /* try to determine if we are going to block */
+ fd_set wrset;
+ int ready;
+ struct timeval timeout;
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 0;
+ FD_ZERO(&wrset);
+ FD_SET( client->fd, &wrset );
+ ready = select(client->fd+1, 0, &wrset, 0, &timeout);
+ //fprintf(stderr,"Ivy: select ready=%d fd=%d\n",ready,FD_ISSET( client->fd, &wrset ) );
+ if(ready < 0) {
+ perror("Ivy: SocketSendRaw select");
+ }
+ if ( !FD_ISSET( client->fd, &wrset ) )
+ {
+ fprintf(stderr,"Ivy: Client Queue Full Waiting..........");
+ waiting = 1;
+ }
+
+ }
err = send (client->fd, buffer, len, 0 );
if (err != len )
perror ("*** send ***");
+ if ( debug_send && waiting )
+ {
+ fprintf(stderr,"... OK\n");
+ }
+ return waiting;
}
void SocketSetData (Client client, void *data )
@@ -394,18 +387,20 @@ void SocketSetData (Client client, void *data )
client->data = data;
}
-void SocketSend (Client client, char *fmt, ... )
+int SocketSend (Client client, char *fmt, ... )
{
- static char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */
- static int size = 0; /* donc non reentrant !!!! */
+ int waiting = 0;
+ static IvyBuffer buffer = {NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
va_list ap;
int len;
if (!client)
- return;
+ return waiting;
va_start (ap, fmt );
- len = make_message (&buffer,&size, 0, fmt, ap );
- SocketSendRaw (client, buffer, len );
+ buffer.offset = 0;
+ len = make_message (&buffer, fmt, ap );
+ waiting = SocketSendRaw (client, buffer.data, len );
va_end (ap );
+ return waiting;
}
void *SocketGetData (Client client )
@@ -416,17 +411,16 @@ void *SocketGetData (Client client )
void SocketBroadcast ( char *fmt, ... )
{
Client client;
- static char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */
- static int size = 0; /* donc non reentrant !!!! */
+ static IvyBuffer buffer = {NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
va_list ap;
int len;
va_start (ap, fmt );
- len = make_message (&buffer, &size, 0, fmt, ap );
+ len = make_message (&buffer, fmt, ap );
va_end (ap );
IVY_LIST_EACH (clients_list, client )
{
- SocketSendRaw (client, buffer, len );
+ SocketSendRaw (client, buffer.data, len );
}
}
@@ -472,12 +466,7 @@ Client SocketConnectAddr (struct in_addr * addr, unsigned short port,
return NULL;
};
- IVY_LIST_ADD (clients_list, client );
- if (!client ) {
- fprintf(stderr,"NOK Memory Alloc Error\n");
- close (handle );
- exit(0);
- }
+ IVY_LIST_ADD_START(clients_list, client );
client->buffer_size = BUFFER_SIZE;
client->buffer = malloc( client->buffer_size );
@@ -496,6 +485,8 @@ Client SocketConnectAddr (struct in_addr * addr, unsigned short port,
client->from.sin_family = AF_INET;
client->from.sin_addr = *addr;
client->from.sin_port = htons (port);
+ IVY_LIST_ADD_END(clients_list, client );
+
return client;
}
// TODO factoriser avec HandleRead !!!!
@@ -600,34 +591,30 @@ Client SocketBroadcastCreate (unsigned short port,
return NULL;
};
- IVY_LIST_ADD(clients_list, client );
- if (!client ) {
- fprintf(stderr,"NOK Memory Alloc Error\n");
- close (handle );
- exit(0);
- }
+ IVY_LIST_ADD_START(clients_list, client );
client->buffer_size = BUFFER_SIZE;
client->buffer = malloc( client->buffer_size );
if (!client->buffer )
{
- fprintf(stderr,"HandleSocket Buffer Memory Alloc Error\n");
+ perror("HandleSocket Buffer Memory Alloc Error: ");
exit(0);
}
- client->terminator = '\n';
+ client->terminator = '\n';
client->fd = handle;
client->channel = (*channel_setup) (handle, client, DeleteSocket, HandleSocket );
client->interpretation = interpretation;
client->ptr = client->buffer;
client->data = data;
+ IVY_LIST_ADD_END(clients_list, client );
+
return client;
}
void SocketSendBroadcast (Client client, unsigned long host, unsigned short port, char *fmt, ... )
{
struct sockaddr_in remote;
- static char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */
- static int size = 0; /* donc non reentrant !!!! */
+ static IvyBuffer buffer = { NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
va_list ap;
int err,len;
@@ -635,13 +622,14 @@ void SocketSendBroadcast (Client client, unsigned long host, unsigned short port
return;
va_start (ap, fmt );
- len = make_message (&buffer, &size, 0, fmt, ap );
+ buffer.offset = 0;
+ len = make_message (&buffer, fmt, ap );
/* Send UDP packet to the dest */
remote.sin_family = AF_INET;
remote.sin_addr.s_addr = htonl (host );
remote.sin_port = htons(port);
err = sendto (client->fd,
- buffer, len,0,
+ buffer.data, len,0,
(struct sockaddr *)&remote,sizeof(remote));
if (err != len) {
perror ("*** send ***");
diff --git a/src/ivysocket.h b/src/ivysocket.h
index 4602b64..c656312 100644
--- a/src/ivysocket.h
+++ b/src/ivysocket.h
@@ -48,9 +48,6 @@ extern "C" {
/* General Init */
extern void SocketInit();
-/* utility fonction do make vsprintf without buffer limit */
-extern int make_message(char ** buffer, int *size, int offset, const char *fmt, va_list ap);
-extern int make_message_var(char ** buffer, int *size, int offset, const char *fmt, ...);
/* Forward def */
typedef struct _client *Client;
@@ -68,8 +65,8 @@ extern void SocketServerClose( Server server );
/* Client Part */
extern void SocketClose( Client client );
-extern void SocketSend( Client client, char *fmt, ... );
-extern void SocketSendRaw( Client client, char *buffer, int len );
+extern int SocketSend( Client client, char *fmt, ... );
+extern int SocketSendRaw( Client client, char *buffer, int len );
extern char *SocketGetPeerHost( Client client );
extern void SocketSetData( Client client, void *data );
extern void *SocketGetData( Client client );
diff --git a/src/list.h b/src/list.h
index 472d2fc..968f619 100644
--- a/src/list.h
+++ b/src/list.h
@@ -50,14 +50,24 @@
}\
} \
}
-
-#define IVY_LIST_ADD(list, p ) \
+/*
+on place le code d'initialisation de l'objet entre START et END
+pour eviter de chainer un objet non initialise
+*/
+#define IVY_LIST_ADD_START(list, p ) \
if ((p = (TYPEOF(p)) (malloc( sizeof( *p ))))) \
{ \
- memset( p, 0 , sizeof( *p ));\
+ memset( p, 0 , sizeof( *p ));
+
+#define IVY_LIST_ADD_END(list, p ) \
p->next = list; \
list = p; \
- }
+ } \
+ else \
+ { \
+ perror( "IVY LIST ADD malloc" ); \
+ exit(0); \
+ }
#define IVY_LIST_EACH( list, p ) \
for ( p = list ; p ; p = p -> next )
diff --git a/src/timer.c b/src/timer.c
index f147232..565271e 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -103,18 +103,16 @@ TimerId TimerRepeatAfter( int count, long time, TimerCb cb, void *user_data )
/* si y a rien a faire et ben on fait rien */
if ( cb == NULL ) return NULL;
- IVY_LIST_ADD( timers, timer )
- if ( timer )
- {
- timer->repeat = count;
- timer->callback = cb;
- timer->user_data = user_data;
- stamp = currentTime();
- timer->period = time;
- timer->when = stamp + time;
- if ( (timer->when < nextTimeout) || (timeoutptr == NULL))
- SetNewTimeout( stamp, timer->when );
- }
+ IVY_LIST_ADD_START( timers, timer )
+ timer->repeat = count;
+ timer->callback = cb;
+ timer->user_data = user_data;
+ stamp = currentTime();
+ timer->period = time;
+ timer->when = stamp + time;
+ if ( (timer->when < nextTimeout) || (timeoutptr == NULL))
+ SetNewTimeout( stamp, timer->when );
+ IVY_LIST_ADD_END( timers, timer )
return timer;
}
void TimerRemove( TimerId timer )