mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-04 04:39:20 +02:00
Copy glib/giowin32.c MAIN to glib-2-2 branch for:
* glib/giowin32.c: Resolved thread deadlocks in socket ichannel code to support Add-Cancel-Add watch functionality on windows. Also cleaned up socket error handling to not segfault and do the right thing. <alanoix@umich.edu> * glib/giowin32.c: Fix indentation and spacing. Use INADDR_LOOPBACK instead of inet_addr("127.0.0.1") and gethostbyaddr(). <tml@iki.fi>
This commit is contained in:
13
ChangeLog
13
ChangeLog
@@ -1,3 +1,16 @@
|
|||||||
|
Sat Jun 28 16:25:31.15 2003 Andrew Lanoix <alanoix@umich.edu>
|
||||||
|
|
||||||
|
Copy glib/giowin32.c MAIN to glib-2-2 branch for:
|
||||||
|
|
||||||
|
* glib/giowin32.c: Resolved thread deadlocks in socket
|
||||||
|
ichannel code to support Add-Cancel-Add watch functionality
|
||||||
|
on windows. Also cleaned up socket error handling to not
|
||||||
|
segfault and do the right thing. <alanoix@umich.edu>
|
||||||
|
|
||||||
|
* glib/giowin32.c: Fix indentation and spacing. Use
|
||||||
|
INADDR_LOOPBACK instead of inet_addr("127.0.0.1") and
|
||||||
|
gethostbyaddr(). <tml@iki.fi>
|
||||||
|
|
||||||
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
||||||
|
@@ -1,3 +1,16 @@
|
|||||||
|
Sat Jun 28 16:25:31.15 2003 Andrew Lanoix <alanoix@umich.edu>
|
||||||
|
|
||||||
|
Copy glib/giowin32.c MAIN to glib-2-2 branch for:
|
||||||
|
|
||||||
|
* glib/giowin32.c: Resolved thread deadlocks in socket
|
||||||
|
ichannel code to support Add-Cancel-Add watch functionality
|
||||||
|
on windows. Also cleaned up socket error handling to not
|
||||||
|
segfault and do the right thing. <alanoix@umich.edu>
|
||||||
|
|
||||||
|
* glib/giowin32.c: Fix indentation and spacing. Use
|
||||||
|
INADDR_LOOPBACK instead of inet_addr("127.0.0.1") and
|
||||||
|
gethostbyaddr(). <tml@iki.fi>
|
||||||
|
|
||||||
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
||||||
|
@@ -1,3 +1,16 @@
|
|||||||
|
Sat Jun 28 16:25:31.15 2003 Andrew Lanoix <alanoix@umich.edu>
|
||||||
|
|
||||||
|
Copy glib/giowin32.c MAIN to glib-2-2 branch for:
|
||||||
|
|
||||||
|
* glib/giowin32.c: Resolved thread deadlocks in socket
|
||||||
|
ichannel code to support Add-Cancel-Add watch functionality
|
||||||
|
on windows. Also cleaned up socket error handling to not
|
||||||
|
segfault and do the right thing. <alanoix@umich.edu>
|
||||||
|
|
||||||
|
* glib/giowin32.c: Fix indentation and spacing. Use
|
||||||
|
INADDR_LOOPBACK instead of inet_addr("127.0.0.1") and
|
||||||
|
gethostbyaddr(). <tml@iki.fi>
|
||||||
|
|
||||||
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
||||||
|
@@ -1,3 +1,16 @@
|
|||||||
|
Sat Jun 28 16:25:31.15 2003 Andrew Lanoix <alanoix@umich.edu>
|
||||||
|
|
||||||
|
Copy glib/giowin32.c MAIN to glib-2-2 branch for:
|
||||||
|
|
||||||
|
* glib/giowin32.c: Resolved thread deadlocks in socket
|
||||||
|
ichannel code to support Add-Cancel-Add watch functionality
|
||||||
|
on windows. Also cleaned up socket error handling to not
|
||||||
|
segfault and do the right thing. <alanoix@umich.edu>
|
||||||
|
|
||||||
|
* glib/giowin32.c: Fix indentation and spacing. Use
|
||||||
|
INADDR_LOOPBACK instead of inet_addr("127.0.0.1") and
|
||||||
|
gethostbyaddr(). <tml@iki.fi>
|
||||||
|
|
||||||
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
||||||
|
@@ -1,3 +1,16 @@
|
|||||||
|
Sat Jun 28 16:25:31.15 2003 Andrew Lanoix <alanoix@umich.edu>
|
||||||
|
|
||||||
|
Copy glib/giowin32.c MAIN to glib-2-2 branch for:
|
||||||
|
|
||||||
|
* glib/giowin32.c: Resolved thread deadlocks in socket
|
||||||
|
ichannel code to support Add-Cancel-Add watch functionality
|
||||||
|
on windows. Also cleaned up socket error handling to not
|
||||||
|
segfault and do the right thing. <alanoix@umich.edu>
|
||||||
|
|
||||||
|
* glib/giowin32.c: Fix indentation and spacing. Use
|
||||||
|
INADDR_LOOPBACK instead of inet_addr("127.0.0.1") and
|
||||||
|
gethostbyaddr(). <tml@iki.fi>
|
||||||
|
|
||||||
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
||||||
|
@@ -1,3 +1,16 @@
|
|||||||
|
Sat Jun 28 16:25:31.15 2003 Andrew Lanoix <alanoix@umich.edu>
|
||||||
|
|
||||||
|
Copy glib/giowin32.c MAIN to glib-2-2 branch for:
|
||||||
|
|
||||||
|
* glib/giowin32.c: Resolved thread deadlocks in socket
|
||||||
|
ichannel code to support Add-Cancel-Add watch functionality
|
||||||
|
on windows. Also cleaned up socket error handling to not
|
||||||
|
segfault and do the right thing. <alanoix@umich.edu>
|
||||||
|
|
||||||
|
* glib/giowin32.c: Fix indentation and spacing. Use
|
||||||
|
INADDR_LOOPBACK instead of inet_addr("127.0.0.1") and
|
||||||
|
gethostbyaddr(). <tml@iki.fi>
|
||||||
|
|
||||||
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
2003-06-25 Tor Lillqvist <tml@iki.fi>
|
||||||
|
|
||||||
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
* glib/giowin32.c (g_io_channel_unix_new): Pass real &optval and
|
||||||
|
159
glib/giowin32.c
159
glib/giowin32.c
@@ -4,7 +4,7 @@
|
|||||||
* giowin32.c: IO Channels for Win32.
|
* giowin32.c: IO Channels for Win32.
|
||||||
* Copyright 1998 Owen Taylor and Tor Lillqvist
|
* Copyright 1998 Owen Taylor and Tor Lillqvist
|
||||||
* Copyright 1999-2000 Tor Lillqvist and Craig Setera
|
* Copyright 1999-2000 Tor Lillqvist and Craig Setera
|
||||||
* Copyright 2001 Andrew Lanoix
|
* Copyright 2001-2003 Andrew Lanoix
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -110,6 +110,8 @@ struct _GIOWin32Channel {
|
|||||||
/* Following fields used by socket channels */
|
/* Following fields used by socket channels */
|
||||||
GSList *watches;
|
GSList *watches;
|
||||||
HANDLE data_avail_noticed_event;
|
HANDLE data_avail_noticed_event;
|
||||||
|
gint reset_send; /* socket used to send data so select_thread() can reset/re-loop */
|
||||||
|
gint reset_recv; /* socket used to recv data so select_thread() can reset/re-loop */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LOCK(mutex) EnterCriticalSection (&mutex)
|
#define LOCK(mutex) EnterCriticalSection (&mutex)
|
||||||
@@ -340,6 +342,66 @@ create_thread (GIOWin32Channel *channel,
|
|||||||
WaitForSingleObject (channel->space_avail_event, INFINITE);
|
WaitForSingleObject (channel->space_avail_event, INFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_reset_sockets (GIOWin32Channel *channel)
|
||||||
|
{
|
||||||
|
struct sockaddr_in local, local2, server;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
channel->reset_send = (gint) socket (AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (channel->reset_send == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC ": Error creating reset_send socket: %s\n",
|
||||||
|
g_win32_error_message (WSAGetLastError ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
local.sin_family = AF_INET;
|
||||||
|
local.sin_port = 0;
|
||||||
|
local.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||||
|
|
||||||
|
if (bind (channel->reset_send, (struct sockaddr *)&local, sizeof (local)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC ": Error binding to reset_send socket: %s\n",
|
||||||
|
g_win32_error_message (WSAGetLastError ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
local2.sin_family = AF_INET;
|
||||||
|
local2.sin_port = 0;
|
||||||
|
local2.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||||
|
|
||||||
|
channel->reset_recv = (gint) socket (AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (channel->reset_recv == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC ": Error creating reset_recv socket: %s\n",
|
||||||
|
g_win32_error_message (WSAGetLastError ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind (channel->reset_recv, (struct sockaddr *)&local2, sizeof (local)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC ": Error binding to reset_recv socket: %s\n",
|
||||||
|
g_win32_error_message (WSAGetLastError ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
len = sizeof (local2);
|
||||||
|
if (getsockname (channel->reset_recv, (struct sockaddr *)&local2, &len) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC ": Error getsockname with reset_recv socket: %s\n",
|
||||||
|
g_win32_error_message (WSAGetLastError ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&server, 0, sizeof (server));
|
||||||
|
server.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||||
|
server.sin_family = AF_INET;
|
||||||
|
server.sin_port = local2.sin_port;
|
||||||
|
|
||||||
|
if (connect (channel->reset_send, (struct sockaddr *)&server, sizeof (server)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC ": connect to reset_recv socket: %s\n",
|
||||||
|
g_win32_error_message (WSAGetLastError ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static GIOStatus
|
static GIOStatus
|
||||||
buffer_read (GIOWin32Channel *channel,
|
buffer_read (GIOWin32Channel *channel,
|
||||||
guchar *dest,
|
guchar *dest,
|
||||||
@@ -417,6 +479,7 @@ select_thread (void *parameter)
|
|||||||
fd_set read_fds, write_fds, except_fds;
|
fd_set read_fds, write_fds, except_fds;
|
||||||
GSList *tmp;
|
GSList *tmp;
|
||||||
int n;
|
int n;
|
||||||
|
char buffer[8];
|
||||||
|
|
||||||
g_io_channel_ref ((GIOChannel *)channel);
|
g_io_channel_ref ((GIOChannel *)channel);
|
||||||
|
|
||||||
@@ -437,7 +500,9 @@ select_thread (void *parameter)
|
|||||||
FD_ZERO (&read_fds);
|
FD_ZERO (&read_fds);
|
||||||
FD_ZERO (&write_fds);
|
FD_ZERO (&write_fds);
|
||||||
FD_ZERO (&except_fds);
|
FD_ZERO (&except_fds);
|
||||||
|
FD_SET (channel->reset_recv, &read_fds);
|
||||||
|
|
||||||
|
LOCK (channel->mutex);
|
||||||
tmp = channel->watches;
|
tmp = channel->watches;
|
||||||
while (tmp)
|
while (tmp)
|
||||||
{
|
{
|
||||||
@@ -452,6 +517,8 @@ select_thread (void *parameter)
|
|||||||
|
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
UNLOCK (channel->mutex);
|
||||||
|
|
||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
g_print ("select_thread %#x: calling select() for%s%s%s\n",
|
g_print ("select_thread %#x: calling select() for%s%s%s\n",
|
||||||
channel->thread_id,
|
channel->thread_id,
|
||||||
@@ -461,6 +528,14 @@ select_thread (void *parameter)
|
|||||||
|
|
||||||
n = select (1, &read_fds, &write_fds, &except_fds, NULL);
|
n = select (1, &read_fds, &write_fds, &except_fds, NULL);
|
||||||
|
|
||||||
|
LOCK (channel->mutex);
|
||||||
|
if (channel->needs_close)
|
||||||
|
{
|
||||||
|
UNLOCK (channel->mutex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
UNLOCK (channel->mutex);
|
||||||
|
|
||||||
if (n == SOCKET_ERROR)
|
if (n == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
@@ -469,6 +544,15 @@ select_thread (void *parameter)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FD_ISSET (channel->reset_recv, &read_fds))
|
||||||
|
{
|
||||||
|
if (channel->debug)
|
||||||
|
g_print ("select_thread %#x: re-looping\n",
|
||||||
|
channel->thread_id);
|
||||||
|
recv (channel->reset_recv, (char *)&buffer, (int) sizeof (buffer), 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
g_print ("select_thread %#x: got%s%s%s\n",
|
g_print ("select_thread %#x: got%s%s%s\n",
|
||||||
channel->thread_id,
|
channel->thread_id,
|
||||||
@@ -486,10 +570,10 @@ select_thread (void *parameter)
|
|||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
g_print ("select_thread %#x: resetting data_avail_noticed, setting data_avail\n",
|
g_print ("select_thread %#x: resetting data_avail_noticed, setting data_avail\n",
|
||||||
channel->thread_id);
|
channel->thread_id);
|
||||||
ResetEvent (channel->data_avail_noticed_event);
|
|
||||||
SetEvent (channel->data_avail_event);
|
|
||||||
|
|
||||||
LOCK (channel->mutex);
|
LOCK (channel->mutex);
|
||||||
|
ResetEvent (channel->data_avail_noticed_event);
|
||||||
|
SetEvent (channel->data_avail_event);
|
||||||
if (channel->needs_close)
|
if (channel->needs_close)
|
||||||
{
|
{
|
||||||
UNLOCK (channel->mutex);
|
UNLOCK (channel->mutex);
|
||||||
@@ -507,21 +591,14 @@ select_thread (void *parameter)
|
|||||||
channel->thread_id);
|
channel->thread_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->running = FALSE;
|
|
||||||
LOCK (channel->mutex);
|
LOCK (channel->mutex);
|
||||||
if (channel->fd != -1)
|
channel->running = FALSE;
|
||||||
{
|
|
||||||
/* DO NOT close the fd here */
|
|
||||||
channel->fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
g_print ("select_thread %#x: got error, setting data_avail\n",
|
g_print ("select_thread %#x: got error, setting data_avail\n",
|
||||||
channel->thread_id);
|
channel->thread_id);
|
||||||
SetEvent (channel->data_avail_event);
|
SetEvent (channel->data_avail_event);
|
||||||
UNLOCK (channel->mutex);
|
|
||||||
|
|
||||||
g_io_channel_unref ((GIOChannel *)channel);
|
g_io_channel_unref ((GIOChannel *)channel);
|
||||||
|
UNLOCK (channel->mutex);
|
||||||
|
|
||||||
/* No need to call _endthreadex(), the actual thread starter routine
|
/* No need to call _endthreadex(), the actual thread starter routine
|
||||||
* in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
|
* in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
|
||||||
@@ -561,8 +638,8 @@ g_io_win32_prepare (GSource *source,
|
|||||||
}
|
}
|
||||||
else if (channel->type == G_IO_WIN32_SOCKET)
|
else if (channel->type == G_IO_WIN32_SOCKET)
|
||||||
{
|
{
|
||||||
|
LOCK (channel->mutex);
|
||||||
channel->revents = 0;
|
channel->revents = 0;
|
||||||
|
|
||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
g_print ("g_io_win32_prepare: for thread %#x, setting data_avail_noticed\n",
|
g_print ("g_io_win32_prepare: for thread %#x, setting data_avail_noticed\n",
|
||||||
channel->thread_id);
|
channel->thread_id);
|
||||||
@@ -570,6 +647,7 @@ g_io_win32_prepare (GSource *source,
|
|||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
g_print ("g_io_win32_prepare: thread %#x, there.\n",
|
g_print ("g_io_win32_prepare: thread %#x, there.\n",
|
||||||
channel->thread_id);
|
channel->thread_id);
|
||||||
|
UNLOCK (channel->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((watch->condition & buffer_condition) == watch->condition);
|
return ((watch->condition & buffer_condition) == watch->condition);
|
||||||
@@ -600,6 +678,7 @@ g_io_win32_check (GSource *source)
|
|||||||
|
|
||||||
if (channel->type == G_IO_WIN32_SOCKET)
|
if (channel->type == G_IO_WIN32_SOCKET)
|
||||||
{
|
{
|
||||||
|
LOCK (channel->mutex);
|
||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
g_print ("g_io_win32_check: thread %#x, resetting data_avail\n",
|
g_print ("g_io_win32_check: thread %#x, resetting data_avail\n",
|
||||||
channel->thread_id);
|
channel->thread_id);
|
||||||
@@ -607,6 +686,7 @@ g_io_win32_check (GSource *source)
|
|||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
g_print ("g_io_win32_check: thread %#x, there.\n",
|
g_print ("g_io_win32_check: thread %#x, there.\n",
|
||||||
channel->thread_id);
|
channel->thread_id);
|
||||||
|
UNLOCK (channel->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((watch->pollfd.revents | buffer_condition) & watch->condition);
|
return ((watch->pollfd.revents | buffer_condition) & watch->condition);
|
||||||
@@ -638,7 +718,9 @@ g_io_win32_finalize (GSource *source)
|
|||||||
{
|
{
|
||||||
GIOWin32Watch *watch = (GIOWin32Watch *)source;
|
GIOWin32Watch *watch = (GIOWin32Watch *)source;
|
||||||
GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
|
GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
|
||||||
|
char send_buffer[] = "f";
|
||||||
|
|
||||||
|
LOCK (channel->mutex);
|
||||||
if (channel->debug)
|
if (channel->debug)
|
||||||
g_print ("g_io_win32_finalize: channel with thread %#x\n",
|
g_print ("g_io_win32_finalize: channel with thread %#x\n",
|
||||||
channel->thread_id);
|
channel->thread_id);
|
||||||
@@ -646,7 +728,11 @@ g_io_win32_finalize (GSource *source)
|
|||||||
channel->watches = g_slist_remove (channel->watches, watch);
|
channel->watches = g_slist_remove (channel->watches, watch);
|
||||||
|
|
||||||
SetEvent (channel->data_avail_noticed_event);
|
SetEvent (channel->data_avail_noticed_event);
|
||||||
|
if (channel->type == G_IO_WIN32_SOCKET)
|
||||||
|
send (channel->reset_send, send_buffer, sizeof (send_buffer), 0);
|
||||||
|
|
||||||
g_io_channel_unref (watch->channel);
|
g_io_channel_unref (watch->channel);
|
||||||
|
UNLOCK (channel->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(G_PLATFORM_WIN32) && defined(__GNUC__)
|
#if defined(G_PLATFORM_WIN32) && defined(__GNUC__)
|
||||||
@@ -667,6 +753,7 @@ g_io_win32_create_watch (GIOChannel *channel,
|
|||||||
GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
|
GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
|
||||||
GIOWin32Watch *watch;
|
GIOWin32Watch *watch;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
char send_buffer[] = "c";
|
||||||
|
|
||||||
source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
|
source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
|
||||||
watch = (GIOWin32Watch *)source;
|
watch = (GIOWin32Watch *)source;
|
||||||
@@ -686,12 +773,16 @@ g_io_win32_create_watch (GIOChannel *channel,
|
|||||||
g_print ("g_io_win32_create_watch: fd:%d condition:%#x handle:%#x\n",
|
g_print ("g_io_win32_create_watch: fd:%d condition:%#x handle:%#x\n",
|
||||||
win32_channel->fd, condition, watch->pollfd.fd);
|
win32_channel->fd, condition, watch->pollfd.fd);
|
||||||
|
|
||||||
|
LOCK (win32_channel->mutex);
|
||||||
win32_channel->watches = g_slist_append (win32_channel->watches, watch);
|
win32_channel->watches = g_slist_append (win32_channel->watches, watch);
|
||||||
|
|
||||||
if (win32_channel->thread_id == 0)
|
if (win32_channel->thread_id == 0)
|
||||||
create_thread (win32_channel, condition, thread);
|
create_thread (win32_channel, condition, thread);
|
||||||
|
else
|
||||||
|
send (win32_channel->reset_send, send_buffer, sizeof (send_buffer), 0);
|
||||||
|
|
||||||
g_source_add_poll (source, &watch->pollfd);
|
g_source_add_poll (source, &watch->pollfd);
|
||||||
|
UNLOCK (win32_channel->mutex);
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
@@ -709,7 +800,7 @@ g_io_win32_msg_read (GIOChannel *channel,
|
|||||||
if (count < sizeof (MSG))
|
if (count < sizeof (MSG))
|
||||||
{
|
{
|
||||||
g_set_error (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
|
g_set_error (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
|
||||||
_("Incorrect message size")); /* Informative enough error message? */
|
"Incorrect message size"); /* Informative enough error message? */
|
||||||
return G_IO_STATUS_ERROR;
|
return G_IO_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,7 +829,7 @@ g_io_win32_msg_write (GIOChannel *channel,
|
|||||||
if (count != sizeof (MSG))
|
if (count != sizeof (MSG))
|
||||||
{
|
{
|
||||||
g_set_error (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
|
g_set_error (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
|
||||||
_("Incorrect message size")); /* Informative enough error message? */
|
"Incorrect message size"); /* Informative enough error message? */
|
||||||
return G_IO_STATUS_ERROR;
|
return G_IO_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -776,6 +867,10 @@ g_io_win32_free (GIOChannel *channel)
|
|||||||
win32_channel->thread_id,
|
win32_channel->thread_id,
|
||||||
win32_channel->fd);
|
win32_channel->fd);
|
||||||
|
|
||||||
|
if (win32_channel->reset_send)
|
||||||
|
closesocket (win32_channel->reset_send);
|
||||||
|
if (win32_channel->reset_recv)
|
||||||
|
closesocket (win32_channel->reset_recv);
|
||||||
if (win32_channel->data_avail_event)
|
if (win32_channel->data_avail_event)
|
||||||
CloseHandle (win32_channel->data_avail_event);
|
CloseHandle (win32_channel->data_avail_event);
|
||||||
if (win32_channel->space_avail_event)
|
if (win32_channel->space_avail_event)
|
||||||
@@ -999,7 +1094,9 @@ g_io_win32_sock_read (GIOChannel *channel,
|
|||||||
{
|
{
|
||||||
GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
|
GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
|
||||||
gint result;
|
gint result;
|
||||||
GIOChannelError error;
|
GIOChannelError error = G_IO_STATUS_NORMAL;
|
||||||
|
GIOStatus internal_status = G_IO_STATUS_NORMAL;
|
||||||
|
char send_buffer[] = "sr";
|
||||||
|
|
||||||
if (win32_channel->debug)
|
if (win32_channel->debug)
|
||||||
g_print ("g_io_win32_sock_read: sockfd:%d count:%d\n",
|
g_print ("g_io_win32_sock_read: sockfd:%d count:%d\n",
|
||||||
@@ -1031,16 +1128,27 @@ repeat:
|
|||||||
error = G_IO_CHANNEL_ERROR_FAILED;
|
error = G_IO_CHANNEL_ERROR_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
g_set_error(err, G_IO_CHANNEL_ERROR, error, _("Socket error"));
|
g_set_error (err, G_IO_CHANNEL_ERROR, error, "Socket read error");
|
||||||
return G_IO_STATUS_ERROR;
|
internal_status = G_IO_STATUS_ERROR;
|
||||||
/* FIXME get all errors, better error messages */
|
/* FIXME get all errors, better error messages */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*bytes_read = result;
|
*bytes_read = result;
|
||||||
|
if (result == 0)
|
||||||
return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
|
internal_status = G_IO_STATUS_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((internal_status == G_IO_STATUS_EOF) ||
|
||||||
|
(internal_status == G_IO_STATUS_ERROR))
|
||||||
|
{
|
||||||
|
LOCK (win32_channel->mutex);
|
||||||
|
SetEvent (win32_channel->data_avail_noticed_event);
|
||||||
|
win32_channel->needs_close = 1;
|
||||||
|
send (win32_channel->reset_send, send_buffer, sizeof (send_buffer), 0);
|
||||||
|
UNLOCK (win32_channel->mutex);
|
||||||
|
}
|
||||||
|
return internal_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GIOStatus
|
static GIOStatus
|
||||||
@@ -1052,7 +1160,8 @@ g_io_win32_sock_write (GIOChannel *channel,
|
|||||||
{
|
{
|
||||||
GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
|
GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
|
||||||
gint result;
|
gint result;
|
||||||
GIOChannelError error;
|
GIOChannelError error = G_IO_STATUS_NORMAL;
|
||||||
|
char send_buffer[] = "sw";
|
||||||
|
|
||||||
if (win32_channel->debug)
|
if (win32_channel->debug)
|
||||||
g_print ("g_io_win32_sock_write: sockfd:%d count:%d\n",
|
g_print ("g_io_win32_sock_write: sockfd:%d count:%d\n",
|
||||||
@@ -1084,7 +1193,12 @@ repeat:
|
|||||||
error = G_IO_CHANNEL_ERROR_FAILED;
|
error = G_IO_CHANNEL_ERROR_FAILED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
g_set_error(err, G_IO_CHANNEL_ERROR, error, _("Socket error"));
|
g_set_error (err, G_IO_CHANNEL_ERROR, error, "Socket write error");
|
||||||
|
LOCK (win32_channel->mutex);
|
||||||
|
SetEvent (win32_channel->data_avail_noticed_event);
|
||||||
|
win32_channel->needs_close = 1;
|
||||||
|
send (win32_channel->reset_send, send_buffer, sizeof (send_buffer), 0);
|
||||||
|
UNLOCK (win32_channel->mutex);
|
||||||
return G_IO_STATUS_ERROR;
|
return G_IO_STATUS_ERROR;
|
||||||
/* FIXME get all errors, better error messages */
|
/* FIXME get all errors, better error messages */
|
||||||
}
|
}
|
||||||
@@ -1471,6 +1585,7 @@ g_io_channel_win32_new_socket (int socket)
|
|||||||
|
|
||||||
g_io_channel_init (channel);
|
g_io_channel_init (channel);
|
||||||
g_io_channel_win32_init (win32_channel);
|
g_io_channel_win32_init (win32_channel);
|
||||||
|
init_reset_sockets (win32_channel);
|
||||||
if (win32_channel->debug)
|
if (win32_channel->debug)
|
||||||
g_print ("g_io_channel_win32_new_socket: sockfd:%d\n", socket);
|
g_print ("g_io_channel_win32_new_socket: sockfd:%d\n", socket);
|
||||||
channel->funcs = &win32_channel_sock_funcs;
|
channel->funcs = &win32_channel_sock_funcs;
|
||||||
|
Reference in New Issue
Block a user