pidgin: b25bb386: Gadu-Gadu: move our win32 resolver out o...
tomkiewicz at cpw.pidgin.im
tomkiewicz at cpw.pidgin.im
Mon Oct 17 17:31:27 EDT 2011
----------------------------------------------------------------------
Revision: b25bb3869be9cc4589818113f23267005892c3c6
Parent: ef3258e09ec421ff33e34c2270937200b01b7e8c
Author: tomkiewicz at cpw.pidgin.im
Date: 10/17/11 17:25:53
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/b25bb3869be9cc4589818113f23267005892c3c6
Changelog:
Gadu-Gadu: move our win32 resolver out of libgadu sources. Refs #343
Changes against parent ef3258e09ec421ff33e34c2270937200b01b7e8c
added libpurple/protocols/gg/win32-resolver.c
added libpurple/protocols/gg/win32-resolver.h
patched libpurple/protocols/gg/Makefile.am
patched libpurple/protocols/gg/Makefile.mingw
patched libpurple/protocols/gg/gg.c
patched libpurple/protocols/gg/lib/libgadu.h
patched libpurple/protocols/gg/lib/resolver.c
-------------- next part --------------
============================================================
--- libpurple/protocols/gg/Makefile.am 39591573cf2f0332ebafa1d1c19713b79b06ce9c
+++ libpurple/protocols/gg/Makefile.am 055399a717b226355a566bf0361871637cefec72
@@ -1,5 +1,7 @@ EXTRA_DIST = \
EXTRA_DIST = \
Makefile.mingw \
+ win32-resolver.c \
+ win32-resolver.h \
lib/common.c \
lib/compat.h \
lib/COPYING \
============================================================
--- libpurple/protocols/gg/gg.c 10d65908a48ba6ddb9f583dee1f25a70a3c55b6c
+++ libpurple/protocols/gg/gg.c c79965bdd1e5449dfc037972761e843acc5d931c
@@ -47,6 +47,10 @@
#include "buddylist.h"
#include "gg-utils.h"
+#ifdef _WIN32
+# include "win32-resolver.h"
+#endif
+
static PurplePlugin *my_protocol = NULL;
/* Prototypes */
@@ -3000,6 +3004,11 @@ static void init_plugin(PurplePlugin *pl
my_protocol = plugin;
gg_debug_handler = purple_gg_debug_handler;
+
+#ifdef _WIN32
+ gg_global_set_custom_resolver(ggp_resolver_win32thread_start,
+ ggp_resolver_win32thread_cleanup);
+#endif
}
PURPLE_INIT_PLUGIN(gg, init_plugin, info);
============================================================
--- libpurple/protocols/gg/Makefile.mingw 6365006701bdfeffbbb9264afc22116fd3cb23cf
+++ libpurple/protocols/gg/Makefile.mingw fb7eb47e39a124fb8c47c34856471d014f66eda2
@@ -60,7 +60,8 @@ C_SRC = \
confer.c \
gg.c \
search.c \
- gg-utils.c
+ gg-utils.c \
+ win32-resolver.c
OBJECTS = $(C_SRC:%.c=%.o)
============================================================
--- libpurple/protocols/gg/lib/libgadu.h 3a16d1d0be02034a431087507866d7df145a5f83
+++ libpurple/protocols/gg/lib/libgadu.h 7ad8d5be1fd961be6d118aefac3e07040ca468ae
@@ -95,6 +95,12 @@ extern "C" {
/* Defined if uintX_t types are defined in <sys/types.h>. */
#undef GG_CONFIG_HAVE_SYS_TYPES_H
+#ifdef _WIN32
+# undef GG_CONFIG_HAVE_FORK
+#else
+# define GG_CONFIG_HAVE_FORK
+#endif
+
#ifdef GG_CONFIG_HAVE_OPENSSL
#include <openssl/ssl.h>
#endif
@@ -195,7 +201,6 @@ typedef enum {
GG_RESOLVER_DEFAULT = 0, /**< Domy?lny spos?b rozwi?zywania nazw (jeden z poni?szych) */
GG_RESOLVER_FORK, /**< Rozwi?zywanie nazw bazuj?ce na procesach */
GG_RESOLVER_PTHREAD, /**< Rozwi?zywanie nazw bazuj?ce na w?tkach */
- GG_RESOLVER_WIN32,
GG_RESOLVER_CUSTOM, /**< Funkcje rozwi?zywania nazw dostarczone przed aplikacj? */
GG_RESOLVER_INVALID = -1 /**< Nieprawid?owy spos?b rozwi?zywania nazw (wynik \c gg_session_get_resolver) */
} gg_resolver_t;
============================================================
--- libpurple/protocols/gg/lib/resolver.c 3cf35dc9a196c16e6e9e381385bfd4b832d72d32
+++ libpurple/protocols/gg/lib/resolver.c efa50452dff8b59c868dd6605b35416fca2b4955
@@ -319,283 +319,6 @@ struct gg_resolver_fork_data {
int pid; /*< Identyfikator procesu */
};
-#ifdef _WIN32
-/**
- * Deal with the fact that you can't select() on a win32 file fd.
- * This makes it practically impossible to tie into purple's event loop.
- *
- * -This is thanks to Tor Lillqvist.
- * XXX - Move this to where the rest of the the win32 compatiblity stuff goes when we push the changes back to libgadu.
- */
-static int
-socket_pipe (int *fds)
-{
- SOCKET temp, socket1 = -1, socket2 = -1;
- struct sockaddr_in saddr;
- int len;
- u_long arg;
- fd_set read_set, write_set;
- struct timeval tv;
-
- temp = socket(AF_INET, SOCK_STREAM, 0);
-
- if (temp == INVALID_SOCKET) {
- goto out0;
- }
-
- arg = 1;
- if (ioctlsocket(temp, FIONBIO, &arg) == SOCKET_ERROR) {
- goto out0;
- }
-
- memset(&saddr, 0, sizeof(saddr));
- saddr.sin_family = AF_INET;
- saddr.sin_port = 0;
- saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- if (bind(temp, (struct sockaddr *)&saddr, sizeof (saddr))) {
- goto out0;
- }
-
- if (listen(temp, 1) == SOCKET_ERROR) {
- goto out0;
- }
-
- len = sizeof(saddr);
- if (getsockname(temp, (struct sockaddr *)&saddr, &len)) {
- goto out0;
- }
-
- socket1 = socket(AF_INET, SOCK_STREAM, 0);
-
- if (socket1 == INVALID_SOCKET) {
- goto out0;
- }
-
- arg = 1;
- if (ioctlsocket(socket1, FIONBIO, &arg) == SOCKET_ERROR) {
- goto out1;
- }
-
- if (connect(socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR ||
- WSAGetLastError() != WSAEWOULDBLOCK) {
- goto out1;
- }
-
- FD_ZERO(&read_set);
- FD_SET(temp, &read_set);
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- if (select(0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR) {
- goto out1;
- }
-
- if (!FD_ISSET(temp, &read_set)) {
- goto out1;
- }
-
- socket2 = accept(temp, (struct sockaddr *) &saddr, &len);
- if (socket2 == INVALID_SOCKET) {
- goto out1;
- }
-
- FD_ZERO(&write_set);
- FD_SET(socket1, &write_set);
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- if (select(0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR) {
- goto out2;
- }
-
- if (!FD_ISSET(socket1, &write_set)) {
- goto out2;
- }
-
- arg = 0;
- if (ioctlsocket(socket1, FIONBIO, &arg) == SOCKET_ERROR) {
- goto out2;
- }
-
- arg = 0;
- if (ioctlsocket(socket2, FIONBIO, &arg) == SOCKET_ERROR) {
- goto out2;
- }
-
- fds[0] = socket1;
- fds[1] = socket2;
-
- closesocket (temp);
-
- return 0;
-
-out2:
- closesocket (socket2);
-out1:
- closesocket (socket1);
-out0:
- closesocket (temp);
- errno = EIO; /* XXX */
-
- return -1;
-}
-#endif
-
-
-
-#ifdef _WIN32
-struct gg_resolve_win32thread_data {
- char *hostname;
- int fd;
-};
-
-static DWORD WINAPI gg_resolve_win32thread_thread(LPVOID arg)
-{
- struct gg_resolve_win32thread_data *d = arg;
- struct in_addr addr_ip[2], *addr_list;
- int addr_count;
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_thread() host: %s, fd: %i called\n", d->hostname, d->fd);
-
- if ((addr_ip[0].s_addr = inet_addr(d->hostname)) == INADDR_NONE) {
- /* W przypadku b??du gg_gethostbyname_real() zwr?ci -1
- * i nie zmieni &addr. Tam jest ju? INADDR_NONE,
- * wi?c nie musimy robi? nic wi?cej. */
- if (gg_gethostbyname_real(d->hostname, &addr_list, &addr_count, 0) == -1)
- {
- addr_list = addr_ip;
- }
- } else {
- addr_list = addr_ip;
- addr_ip[1].s_addr = INADDR_NONE;
- addr_count = 1;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_thread() count = %d\n", addr_count);
-
- write(d->fd, addr_list, (addr_count+1) * sizeof(struct in_addr));
- close(d->fd);
-
- free(d->hostname);
- d->hostname = NULL;
-
- free(d);
-
- if (addr_list != addr_ip)
- free(addr_list);
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_thread() done\n");
-
- return 0;
-}
-
-
-static int gg_resolve_win32thread(int *fd, void **resolver, const char *hostname)
-{
- struct gg_resolve_win32thread_data *d = NULL;
- HANDLE h;
- DWORD dwTId;
- int pipes[2], new_errno;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve_win32thread(%p, %p, \"%s\");\n", fd, resolver, hostname);
-
- if (!resolver || !fd || !hostname) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() invalid arguments\n");
- errno = EFAULT;
- return -1;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() creating pipes...\n");
-
- if (socket_pipe(pipes) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() unable to create pipes (errno=%d, %s)\n", errno, strerror(errno));
- return -1;
- }
-
- if (!(d = malloc(sizeof(*d)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() out of memory\n");
- new_errno = errno;
- goto cleanup;
- }
-
- d->hostname = NULL;
-
- if (!(d->hostname = strdup(hostname))) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() out of memory\n");
- new_errno = errno;
- goto cleanup;
- }
-
- d->fd = pipes[1];
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() creating thread...\n");
-
- h = CreateThread(NULL, 0, gg_resolve_win32thread_thread,
- d, 0, &dwTId);
-
- if (h == NULL) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() unable to create thread\n");
- new_errno = errno;
- goto cleanup;
- }
-
- *resolver = h;
- *fd = pipes[0];
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() done\n");
-
- return 0;
-
-cleanup:
- if (d) {
- free(d->hostname);
- free(d);
- }
-
- close(pipes[0]);
- close(pipes[1]);
-
- errno = new_errno;
-
- return -1;
-
-}
-
-static void gg_resolve_win32thread_cleanup(void **priv_data, int force)
-{
- struct gg_resolve_win32thread_data *data;
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() force: %i called\n", force);
-
- if (priv_data == NULL || *priv_data == NULL)
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() priv_data: NULL\n");
- return;
-
- data = (struct gg_resolve_win32thread_data*) *priv_data;
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() data: %s called\n", data->hostname);
- *priv_data = NULL;
-
- if (force) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() force called\n", force);
- //pthread_cancel(data->thread);
- //pthread_join(data->thread, NULL);
- }
-
- free(data->hostname);
- data->hostname = NULL;
-
- if (data->fd != -1) {
- close(data->fd);
- data->fd = -1;
- }
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread_cleanup() done\n");
- free(data);
-}
-#endif
-
#ifndef _WIN32
/**
* \internal Rozwi?zuje nazw? serwera w osobnym procesie.
@@ -873,24 +596,14 @@ int gg_session_set_resolver(struct gg_se
}
#if !defined(GG_CONFIG_HAVE_PTHREAD) || !defined(GG_CONFIG_PTHREAD_DEFAULT)
-# ifdef _WIN32
- type = GG_RESOLVER_WIN32;
-# else
type = GG_RESOLVER_FORK;
-# endif
#else
type = GG_RESOLVER_PTHREAD;
#endif
}
switch (type) {
-#ifdef _WIN32
- case GG_RESOLVER_WIN32:
- gs->resolver_type = type;
- gs->resolver_start = gg_resolve_win32thread;
- gs->resolver_cleanup = gg_resolve_win32thread_cleanup;
- return 0;
-#else
+#ifdef GG_CONFIG_HAVE_FORK
case GG_RESOLVER_FORK:
gs->resolver_type = type;
gs->resolver_start = gg_resolver_fork_start;
@@ -994,24 +707,14 @@ int gg_http_set_resolver(struct gg_http
}
#if !defined(GG_CONFIG_HAVE_PTHREAD) || !defined(GG_CONFIG_PTHREAD_DEFAULT)
-# ifdef _WIN32
- type = GG_RESOLVER_WIN32;
-# else
type = GG_RESOLVER_FORK;
-# endif
#else
type = GG_RESOLVER_PTHREAD;
#endif
}
switch (type) {
-#ifdef _WIN32
- case GG_RESOLVER_WIN32:
- gh->resolver_type = type;
- gh->resolver_start = gg_resolve_win32thread;
- gh->resolver_cleanup = gg_resolve_win32thread_cleanup;
- return 0;
-#else
+#ifdef GG_CONFIG_HAVE_FORK
case GG_RESOLVER_FORK:
gh->resolver_type = type;
gh->resolver_start = gg_resolver_fork_start;
@@ -1089,13 +792,7 @@ int gg_global_set_resolver(gg_resolver_t
gg_global_resolver_cleanup = NULL;
return 0;
-#ifdef _WIN32
- case GG_RESOLVER_WIN32:
- gg_global_resolver_type = type;
- gg_global_resolver_start = gg_resolve_win32thread;
- gg_global_resolver_cleanup = gg_resolve_win32thread_cleanup;
- return 0;
-#else
+#ifdef GG_CONFIG_HAVE_FORK
case GG_RESOLVER_FORK:
gg_global_resolver_type = type;
gg_global_resolver_start = gg_resolver_fork_start;
============================================================
--- /dev/null
+++ libpurple/protocols/gg/win32-resolver.c da6e47112442aa27e477242ca92965cb0dbd0bc9
@@ -0,0 +1,321 @@
+/**
+ * @file win32-resolver.c
+ *
+ * purple
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "win32-resolver.h"
+
+#include <errno.h>
+#include <resolver.h>
+#include "debug.h"
+
+#ifndef _WIN32
+#error "win32thread resolver is not supported on current platform"
+#endif
+
+/**
+ * Deal with the fact that you can't select() on a win32 file fd.
+ * This makes it practically impossible to tie into purple's event loop.
+ *
+ * -This is thanks to Tor Lillqvist.
+ */
+static int ggp_resolver_win32thread_socket_pipe(int *fds)
+{
+ SOCKET temp, socket1 = -1, socket2 = -1;
+ struct sockaddr_in saddr;
+ int len;
+ u_long arg;
+ fd_set read_set, write_set;
+ struct timeval tv;
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_socket_pipe(&%d)\n",
+ *fds);
+
+ temp = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (temp == INVALID_SOCKET) {
+ goto out0;
+ }
+
+ arg = 1;
+ if (ioctlsocket(temp, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out0;
+ }
+
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.sin_family = AF_INET;
+ saddr.sin_port = 0;
+ saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ if (bind(temp, (struct sockaddr *)&saddr, sizeof (saddr))) {
+ goto out0;
+ }
+
+ if (listen(temp, 1) == SOCKET_ERROR) {
+ goto out0;
+ }
+
+ len = sizeof(saddr);
+ if (getsockname(temp, (struct sockaddr *)&saddr, &len)) {
+ goto out0;
+ }
+
+ socket1 = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (socket1 == INVALID_SOCKET) {
+ goto out0;
+ }
+
+ arg = 1;
+ if (ioctlsocket(socket1, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out1;
+ }
+
+ if (connect(socket1, (struct sockaddr *)&saddr, len) != SOCKET_ERROR ||
+ WSAGetLastError() != WSAEWOULDBLOCK) {
+ goto out1;
+ }
+
+ FD_ZERO(&read_set);
+ FD_SET(temp, &read_set);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ if (select(0, &read_set, NULL, NULL, NULL) == SOCKET_ERROR) {
+ goto out1;
+ }
+
+ if (!FD_ISSET(temp, &read_set)) {
+ goto out1;
+ }
+
+ socket2 = accept(temp, (struct sockaddr *) &saddr, &len);
+ if (socket2 == INVALID_SOCKET) {
+ goto out1;
+ }
+
+ FD_ZERO(&write_set);
+ FD_SET(socket1, &write_set);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ if (select(0, NULL, &write_set, NULL, NULL) == SOCKET_ERROR) {
+ goto out2;
+ }
+
+ if (!FD_ISSET(socket1, &write_set)) {
+ goto out2;
+ }
+
+ arg = 0;
+ if (ioctlsocket(socket1, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out2;
+ }
+
+ arg = 0;
+ if (ioctlsocket(socket2, FIONBIO, &arg) == SOCKET_ERROR) {
+ goto out2;
+ }
+
+ fds[0] = socket1;
+ fds[1] = socket2;
+
+ closesocket (temp);
+
+ return 0;
+
+out2:
+ closesocket (socket2);
+out1:
+ closesocket (socket1);
+out0:
+ closesocket (temp);
+ errno = EIO; /* XXX */
+
+ return -1;
+}
+
+struct ggp_resolver_win32thread_data {
+ char *hostname;
+ int fd;
+};
+
+static DWORD WINAPI ggp_resolver_win32thread_thread(LPVOID arg)
+{
+ struct ggp_resolver_win32thread_data *data = arg;
+ struct in_addr addr_ip[2], *addr_list;
+ int addr_count;
+
+ purple_debug_info("gg", "ggp_resolver_win32thread_thread() host: %s, "
+ "fd: %i called\n", data->hostname, data->fd);
+
+ if ((addr_ip[0].s_addr = inet_addr(data->hostname)) == INADDR_NONE) {
+ /* W przypadku b??du gg_gethostbyname_real() zwr?ci -1
+ * i nie zmieni &addr. Tam jest ju? INADDR_NONE,
+ * wi?c nie musimy robi? nic wi?cej. */
+ if (gg_gethostbyname_real(data->hostname, &addr_list,
+ &addr_count, 0) == -1) {
+ addr_list = addr_ip;
+ }
+ } else {
+ addr_list = addr_ip;
+ addr_ip[1].s_addr = INADDR_NONE;
+ addr_count = 1;
+ }
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_thread() "
+ "count = %d\n", addr_count);
+
+ write(data->fd, addr_list, (addr_count+1) * sizeof(struct in_addr));
+ close(data->fd);
+
+ free(data->hostname);
+ data->hostname = NULL;
+
+ free(data);
+
+ if (addr_list != addr_ip)
+ free(addr_list);
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_thread() done\n");
+
+ return 0;
+}
+
+
+int ggp_resolver_win32thread_start(int *fd, void **private_data,
+ const char *hostname)
+{
+ struct ggp_resolver_win32thread_data *data = NULL;
+ HANDLE h;
+ DWORD dwTId;
+ int pipes[2], new_errno;
+
+ purple_debug_info("gg", "ggp_resolver_win32thread_start(%p, %p, "
+ "\"%s\");\n", fd, private_data, hostname);
+
+ if (!private_data || !fd || !hostname) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() "
+ "invalid arguments\n");
+ errno = EFAULT;
+ return -1;
+ }
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_start() creating "
+ "pipes...\n");
+
+ if (ggp_resolver_win32thread_socket_pipe(pipes) == -1) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() "
+ "unable to create pipes (errno=%d, %s)\n",
+ errno, strerror(errno));
+ return -1;
+ }
+
+ if (!(data = malloc(sizeof(*data)))) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() out "
+ "of memory\n");
+ new_errno = errno;
+ goto cleanup;
+ }
+
+ data->hostname = NULL;
+
+ if (!(data->hostname = strdup(hostname))) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() out "
+ "of memory\n");
+ new_errno = errno;
+ goto cleanup;
+ }
+
+ data->fd = pipes[1];
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_start() creating "
+ "thread...\n");
+
+ h = CreateThread(NULL, 0, ggp_resolver_win32thread_thread, data, 0,
+ &dwTId);
+
+ if (h == NULL) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_start() "
+ "unable to create thread\n");
+ new_errno = errno;
+ goto cleanup;
+ }
+
+ *private_data = h;
+ *fd = pipes[0];
+
+ purple_debug_misc("gg", "ggp_resolver_win32thread_start() done\n");
+
+ return 0;
+
+cleanup:
+ if (data) {
+ free(data->hostname);
+ free(data);
+ }
+
+ close(pipes[0]);
+ close(pipes[1]);
+
+ errno = new_errno;
+
+ return -1;
+
+}
+
+void ggp_resolver_win32thread_cleanup(void **private_data, int force)
+{
+ struct ggp_resolver_win32thread_data *data;
+
+ purple_debug_info("gg", "ggp_resolver_win32thread_cleanup() force: %i "
+ "called\n", force);
+
+ if (private_data == NULL || *private_data == NULL) {
+ purple_debug_error("gg", "ggp_resolver_win32thread_cleanup() "
+ "private_data: NULL\n");
+ return;
+ }
+ return; /* XXX */
+
+ data = (struct ggp_resolver_win32thread_data*) *private_data;
+ purple_debug_misc("gg", "ggp_resolver_win32thread_cleanup() data: "
+ "%s called\n", data->hostname);
+ *private_data = NULL;
+
+ if (force) {
+ purple_debug_misc("gg", "ggp_resolver_win32thread_cleanup() "
+ "force called\n");
+ //pthread_cancel(data->thread);
+ //pthread_join(data->thread, NULL);
+ }
+
+ free(data->hostname);
+ data->hostname = NULL;
+
+ if (data->fd != -1) {
+ close(data->fd);
+ data->fd = -1;
+ }
+ purple_debug_info("gg", "ggp_resolver_win32thread_cleanup() done\n");
+ free(data);
+}
+
+/* vim: set ts=8 sts=0 sw=8 noet: */
============================================================
--- /dev/null
+++ libpurple/protocols/gg/win32-resolver.h 3d15a404efa96c7cc0826559c6bb7519495f46be
@@ -0,0 +1,46 @@
+/**
+ * @file win32-resolver.h
+ *
+ * purple
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef _PURPLE_GG_WIN32_RESOLVER
+#define _PURPLE_GG_WIN32_RESOLVER
+
+/**
+ * Starts hostname resolving in new win32 thread.
+ *
+ * @param fd Pointer to variable, where pipe descriptor will be saved.
+ * @param private_data Pointer to variable, where pointer to private data will
+ * be saved.
+ * @param hostname Hostname to resolve.
+ */
+int ggp_resolver_win32thread_start(int *fd, void **private_data,
+ const char *hostname);
+
+/**
+ * Cleans up resources after hostname resolving.
+ *
+ * @param private_data Pointer to variable storing pointer to private data.
+ * @param force TRUE, if resources should be cleaned up even, if
+ * resolving process didn't finished.
+ */
+void ggp_resolver_win32thread_cleanup(void **private_data, int force);
+
+#endif /* _PURPLE_GG_WIN32_RESOLVER */
+
+/* vim: set ts=8 sts=0 sw=8 noet: */
More information about the Commits
mailing list