* BUG: Fix the file descriptor watch manager again.

[GB.NET]
* BUG: If writing on Socket fails, do not raise the Write event.


git-svn-id: svn://localhost/gambas/trunk@2005 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2009-06-07 00:01:59 +00:00
parent 36742ae3ac
commit 2cbf018690
7 changed files with 48 additions and 27 deletions

View file

@ -1,12 +1,12 @@
# Gambas Project File 3.0
# Compiled with Gambas 2.99.0 (r1690)
# Compiled with Gambas 2.99.0 (r1989)
Startup=FrmMain
Icon=serversocket.png
Version=0.0.43
Component=gb.gui
Component=gb.net
Component=gb.net.curl
Environment="GB_GUI=gb.qt"
Environment="GB_GUI=gb.gtk"
TabSize=2
Translate=1
Language=fr

View file

@ -72,10 +72,12 @@ Public Sub Socket_Write()
Return
Endif
Print #hSocket, hSocket.Tag[1]
Print #hSocket, hSocket.Tag[1]; Space$(512)
hSocket.Tag[0] = iInd
Catch
End

View file

@ -239,7 +239,6 @@ extern "C"
void EXPORT GB_EXIT()
{
CWatcher::exit();
}
int EXPORT GB_INFO(const char *key, void **value)
@ -387,6 +386,7 @@ static int my_loop()
CWatcher::Clear();
gApplication::exit();
CWatcher::exit();
return 0;
}

View file

@ -33,7 +33,7 @@
#include "gambas.h"
#include "watcher.h"
static WATCH *watch = NULL;
static WATCH **watch = NULL;
static gboolean watch_adaptor(GIOChannel *source, GIOCondition condition, gpointer param)
{
@ -44,9 +44,9 @@ static gboolean watch_adaptor(GIOChannel *source, GIOCondition condition, gpoint
switch (condition)
{
case G_IO_IN:
(*data->callback_read)( g_io_channel_unix_get_fd(source), GB_WATCH_READ, data->param_read); break;
(*data->callback_read)(data->fd, GB_WATCH_READ, data->param_read); break;
case G_IO_OUT:
(*data->callback_write)( g_io_channel_unix_get_fd(source), GB_WATCH_WRITE, data->param_write); break;
(*data->callback_write)(data->fd, GB_WATCH_WRITE, data->param_write); break;
default: break;
}
@ -55,11 +55,12 @@ static gboolean watch_adaptor(GIOChannel *source, GIOCondition condition, gpoint
void CWatcher::init()
{
GB.NewArray(POINTER(&watch), sizeof(WATCH), 0);
GB.NewArray(POINTER(&watch), sizeof(WATCH *), 0);
}
void CWatcher::exit()
{
Clear();
GB.FreeArray(POINTER(&watch));
}
@ -67,7 +68,7 @@ void CWatcher::Clear()
{
while (count())
{
CWatcher::Add(watch[0].fd, GB_WATCH_NONE, NULL, 0);
CWatcher::Add(watch[0]->fd, GB_WATCH_NONE, NULL, 0);
}
}
@ -79,15 +80,16 @@ void CWatcher::Remove(int fd)
void CWatcher::Add(int fd, int type, void *callback, intptr_t param)
{
WATCH *data = NULL;
WATCH **pwatch;
int i;
//fprintf(stderr, "CWatcher::Add(%d, %d, %p, %d)\n", fd, type, callback, param);
for (i = 0; i < count(); i++)
{
data = &watch[i];
if (data->fd == fd)
if (watch[i]->fd == fd)
{
data = watch[i];
break;
}
}
if (!data)
@ -95,22 +97,28 @@ void CWatcher::Add(int fd, int type, void *callback, intptr_t param)
if (type == GB_WATCH_NONE || !callback)
return;
data = (WATCH *)GB.Add(&watch);
pwatch = (WATCH **)GB.Add(&watch);
GB.Alloc(POINTER(pwatch), sizeof(WATCH));
data = *pwatch;
data->fd = fd;
data->channel = g_io_channel_unix_new(fd);
data->channel_read = data->channel_write = 0;
data->callback_read = data->callback_write = 0;
}
if (data->callback_read && (type == GB_WATCH_NONE || type == GB_WATCH_READ))
{
g_source_remove(data->id_read);
g_io_channel_unref(data->channel_read);
data->callback_read = 0;
data->channel_read = 0;
}
if (data->callback_write && (type == GB_WATCH_NONE || type == GB_WATCH_WRITE))
{
g_source_remove(data->id_write);
g_io_channel_unref(data->channel_write);
data->callback_write = 0;
data->channel_write = 0;
}
if (callback)
@ -118,18 +126,24 @@ void CWatcher::Add(int fd, int type, void *callback, intptr_t param)
if (type == GB_WATCH_READ)
{
data->callback_read = (WATCH_CALLBACK)callback;
data->id_read = g_io_add_watch_full(data->channel, G_PRIORITY_LOW, G_IO_IN, watch_adaptor, (void*)data, NULL);
data->param_read = param;
data->channel_read = g_io_channel_unix_new(fd);
g_io_channel_set_encoding(data->channel_read, NULL, NULL);
data->id_read = g_io_add_watch_full(data->channel_read, G_PRIORITY_LOW, G_IO_IN, watch_adaptor, (void*)data, NULL);
}
else if (type == GB_WATCH_READ)
else if (type == GB_WATCH_WRITE)
{
data->callback_write = (WATCH_CALLBACK)callback;
data->id_write = g_io_add_watch_full(data->channel, G_PRIORITY_LOW, G_IO_OUT, watch_adaptor, (void*)data, NULL);
data->param_write = param;
data->channel_write = g_io_channel_unix_new(fd);
g_io_channel_set_encoding(data->channel_write, NULL, NULL);
data->id_write = g_io_add_watch_full(data->channel_write, G_PRIORITY_LOW, G_IO_OUT, watch_adaptor, (void*)data, NULL);
}
}
if (!data->callback_read && !data->callback_write)
{
g_io_channel_unref(data->channel);
GB.Free(POINTER(&data));
GB.Remove(&watch, i, 1);
}
}

View file

@ -29,18 +29,20 @@
#ifndef __WATCHER_H
#define __WATCHER_H
#include "gambas.h"
#include <gtk/gtk.h>
typedef
void (*WATCH_CALLBACK)(int, int, intptr_t);
GB_WATCH_CALLBACK WATCH_CALLBACK;
typedef
struct {
int fd;
GIOChannel *channel;
GIOChannel *channel_read;
guint id_read;
WATCH_CALLBACK callback_read;
intptr_t param_read;
GIOChannel *channel_write;
guint id_write;
WATCH_CALLBACK callback_write;
intptr_t param_write;

View file

@ -425,14 +425,18 @@ int CSocket_stream_write(GB_STREAM *stream, char *buffer, int len)
//NoBlock++;
//ioctl(THIS->socket,FIONBIO,&NoBlock);
if (GB.CanRaise(THIS, EVENT_Write) && !THIS->watch_write)
if (npos>=0)
{
//fprintf(stderr, "watch write %p\n", THIS);
THIS->watch_write = TRUE;
GB.Watch(THIS->socket, GB_WATCH_WRITE, (void *)callback_write, (intptr_t)THIS);
if (GB.CanRaise(THIS, EVENT_Write) && !THIS->watch_write)
{
//fprintf(stderr, "watch write %p\n", THIS);
THIS->watch_write = TRUE;
GB.Watch(THIS->socket, GB_WATCH_WRITE, (void *)callback_write, (intptr_t)THIS);
}
return 0;
}
if (npos>=0) return 0;
CSocket_stream_internal_error(THIS,-5);
if (THIS->OnClose) THIS->OnClose(_object);
return -1;

View file

@ -547,7 +547,6 @@ typedef
#define GB_WATCH_NONE 0
#define GB_WATCH_READ 1
#define GB_WATCH_WRITE 2
#define GB_WATCH_READ_WRITE 3
/* Type of a watch callback function */