summaryrefslogtreecommitdiffstats
path: root/PICA_nodewait.c
diff options
context:
space:
mode:
authorme_desk <me_desk@fb96df88-216d-11de-830c-f3023f12d8ac>2012-12-27 03:33:59 +0000
committerme_desk <me_desk@fb96df88-216d-11de-830c-f3023f12d8ac>2012-12-27 03:33:59 +0000
commit11e1161d05f3c78728776cef301a304534baea21 (patch)
treec0bb3472fefdf42a142b0e183be1419f8dd1a5f0 /PICA_nodewait.c
parent93649cf80cfc979c5c4a5d54feedb4a526cb0c00 (diff)
downloadpica-pica-11e1161d05f3c78728776cef301a304534baea21.tar.gz
pica-pica-11e1161d05f3c78728776cef301a304534baea21.zip
nodewait - asynchronous DNS resolve and connect to nodes using threads
git-svn-id: svn://localhost/project_picapica/trunk@215 fb96df88-216d-11de-830c-f3023f12d8ac
Diffstat (limited to 'PICA_nodewait.c')
-rw-r--r--PICA_nodewait.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/PICA_nodewait.c b/PICA_nodewait.c
new file mode 100644
index 0000000..2716d18
--- /dev/null
+++ b/PICA_nodewait.c
@@ -0,0 +1,170 @@
+
+#include "PICA_nodewait.h"
+#include "PICA_log.h"
+#include "PICA_common.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef WIN32
+
+#include <windows.h>
+
+#else
+
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#endif
+
+struct nodewait *nodewait_list;
+
+struct nodewait *nodewait_list_addnew()
+{
+struct nodewait *nw;
+
+nw = (struct nodewait*)calloc(1, sizeof(struct nodewait));
+
+if (!nw)
+ return 0;
+
+nw->next = nodewait_list;
+nodewait_list = nw;
+
+nw->state = PICA_NODEWAIT_NEW;
+return nw;
+}
+
+void nodewait_list_delete(struct nodewait *nw)
+{
+struct nodewait **pp = &nodewait_list;
+struct nodewait *p = nodewait_list;
+
+while(p)
+ {
+ if (p == nw)
+ {
+ *pp = nw->next;
+ //
+ //free resources
+ //
+ free(nw);
+
+ return;
+ }
+
+ pp = &p->next;
+ p = p->next;
+ }
+}
+
+#ifdef WIN32
+static DWORD WINAPI nodewait_thread (void *arg)
+#else
+static void *nodewait_thread (void *arg)
+#endif
+{
+struct nodewait *nw = (struct nodewait *)arg;
+struct addrinfo h,*r,*ap;
+char portbuf[8];
+
+nw->state = PICA_NODEWAIT_RUNNING;
+
+memset(&h,0,sizeof(struct addrinfo));
+
+#ifdef AI_IDN
+#define H_AI_FLAGS (AI_ADDRCONFIG | AI_IDN)
+#else
+#define H_AI_FLAGS AI_ADDRCONFIG
+#endif
+
+h.ai_flags=H_AI_FLAGS;
+h.ai_family=AF_INET;//CONF - IPv4, IPv6, IPv4 then IPv6, IPv6 then IPv4
+h.ai_socktype=SOCK_STREAM;
+h.ai_protocol=IPPROTO_TCP;
+
+sprintf(portbuf,"%u",nw->addr.port);
+
+if (0!=getaddrinfo(nw->addr.addr, portbuf, &h, &r))
+ return 0;
+
+ap = r;
+
+while(ap)
+ {
+ nw->nc.sck=socket(ap->ai_family,ap->ai_socktype,ap->ai_protocol);
+ if (nw->nc.sck==SOCKET_ERROR)
+ {
+ ap=ap->ai_next;
+ continue;
+ }
+
+ if (0 != connect(nw->nc.sck,ap->ai_addr,ap->ai_addrlen))
+ {
+ ap=ap->ai_next;
+
+ CLOSE(nw->nc.sck);
+ continue;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+if (ap)
+ {
+ nw->nc.addr=*((struct sockaddr_in*)(ap->ai_addr));
+ freeaddrinfo(r);
+
+ nw->state = PICA_NODEWAIT_FINISHED_OK;
+ return 1;
+ }
+
+freeaddrinfo(r);
+nw->state = PICA_NODEWAIT_FINISHED_ERR;
+return 0;
+}
+
+void nodewait_start_connection(struct PICA_nodeaddr *a)
+{
+struct nodewait *nw;
+#ifndef WIN32
+pthread_t thr;
+pthread_attr_t attr;
+#else
+DWORD thread_id;
+HANDLE thread_h;
+#endif
+
+nw = nodewait_list_addnew();
+
+if (!nw)
+ return;
+
+nw ->addr = *a;
+
+PICA_debug1("starting connection to node %.255s %u ...", nw->addr.addr, nw->addr.port);
+
+#ifndef WIN32
+if (0 != pthread_attr_init(&attr))
+ PICA_error("pthread_attr_init() call failed.");
+
+pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+if (0 != pthread_create(&thr, &attr, nodewait_thread, (void*)nw))
+ PICA_error("unable to create thread: %s", strerror(errno));
+
+pthread_attr_destroy(&attr);
+#else
+thread_h = CreateThread(NULL, 4096, nodewait_thread, (void*)nw, 0, &thread_id);
+
+if (NULL != thread_h)
+ CloseHandle(thread_h);
+else
+ PICA_error("unable to create thread: %u", GetLastError());
+#endif
+}