void sel_thread_destroy(sel_thread_t p) { int i; yaz_mutex_enter(p->mutex); p->stop_flag = 1; yaz_cond_broadcast(p->input_data); yaz_mutex_leave(p->mutex); for (i = 0; i< p->no_threads; i++) yaz_thread_join(&p->thread_id[i], 0); if (p->work_destroy) { queue_trav(p->input_queue, p->work_destroy); queue_trav(p->output_queue, p->work_destroy); } yaz_spipe_destroy(p->spipe); yaz_cond_destroy(&p->input_data); yaz_mutex_destroy(&p->mutex); nmem_destroy(p->nmem); }
yaz_spipe_t yaz_spipe_create(int port_to_use, WRBUF *err_msg) { yaz_spipe_t p = xmalloc(sizeof(*p)); #ifdef WIN32 { WSADATA wsaData; WORD wVersionRequested = MAKEWORD(2, 0); if (WSAStartup( wVersionRequested, &wsaData)) { if (err_msg) wrbuf_printf(*err_msg, "WSAStartup failed"); xfree(p); return 0; } } #endif p->m_fd[0] = p->m_fd[1] = YAZ_INVALID_SOCKET; p->m_socket = YAZ_INVALID_SOCKET; if (port_to_use) { struct sockaddr_in add; struct sockaddr *addr = 0; unsigned int tmpadd; struct sockaddr caddr; #ifdef WIN32 int caddr_len = sizeof(caddr); #else socklen_t caddr_len = sizeof(caddr); #endif fd_set write_set; /* create server socket */ p->m_socket = socket(AF_INET, SOCK_STREAM, 0); if (p->m_socket == YAZ_INVALID_SOCKET) { if (err_msg) wrbuf_printf(*err_msg, "socket call failed"); yaz_spipe_destroy(p); return 0; } #ifndef WIN32 { unsigned long one = 1; if (setsockopt(p->m_socket, SOL_SOCKET, SO_REUSEADDR, (char*) &one, sizeof(one))) { if (err_msg) wrbuf_printf(*err_msg, "setsockopt call failed"); yaz_spipe_destroy(p); return 0; } } #endif /* bind server socket */ add.sin_family = AF_INET; add.sin_port = htons(port_to_use); add.sin_addr.s_addr = INADDR_ANY; addr = ( struct sockaddr *) &add; if (bind(p->m_socket, addr, sizeof(struct sockaddr_in))) { if (err_msg) wrbuf_printf(*err_msg, "could not bind to socket"); yaz_spipe_destroy(p); return 0; } if (listen(p->m_socket, 3) < 0) { if (err_msg) wrbuf_printf(*err_msg, "could not listen on socket"); yaz_spipe_destroy(p); return 0; } /* client socket */ tmpadd = (unsigned) inet_addr("127.0.0.1"); if (!tmpadd) { if (err_msg) wrbuf_printf(*err_msg, "inet_addr failed"); yaz_spipe_destroy(p); return 0; } memcpy(&add.sin_addr.s_addr, &tmpadd, sizeof(struct in_addr)); p->m_fd[1] = socket(AF_INET, SOCK_STREAM, 0); if (p->m_fd[1] == YAZ_INVALID_SOCKET) { if (err_msg) wrbuf_printf(*err_msg, "socket call failed (2)"); yaz_spipe_destroy(p); return 0; } nonblock(p->m_fd[1]); if (connect(p->m_fd[1], addr, sizeof(*addr))) { if ( #ifdef WIN32 WSAGetLastError() != WSAEWOULDBLOCK #else errno != EINPROGRESS #endif ) { if (err_msg) wrbuf_printf(*err_msg, "connect call failed"); yaz_spipe_destroy(p); return 0; } } /* server accept */ p->m_fd[0] = accept(p->m_socket, &caddr, &caddr_len); if (p->m_fd[0] == YAZ_INVALID_SOCKET) { if (err_msg) wrbuf_printf(*err_msg, "accept failed"); yaz_spipe_destroy(p); return 0; } /* complete connect */ FD_ZERO(&write_set); FD_SET(p->m_fd[1], &write_set); if (select(p->m_fd[1]+1, 0, &write_set, 0, 0) != 1) { if (err_msg) wrbuf_printf(*err_msg, "could not complete connect"); yaz_spipe_destroy(p); return 0; } yaz_spipe_close(&p->m_socket); } else { #ifdef WIN32 yaz_spipe_destroy(p); return 0; #else if (pipe(p->m_fd)) { if (err_msg) wrbuf_printf(*err_msg, "pipe call failed"); yaz_spipe_destroy(p); return 0; } assert(p->m_fd[0] != YAZ_INVALID_SOCKET); assert(p->m_fd[1] != YAZ_INVALID_SOCKET); #endif } return p; }