socketcollection.cc
来自「编译工具」· CC 代码 · 共 716 行 · 第 1/2 页
CC
716 行
// -*- Mode: C++; -*-// Package : omniORB// SocketCollection.cc Created on: 23 Jul 2001// Author : Sai Lai Lo (sll)//// Copyright (C) 2001 AT&T Laboratories Cambridge//// This file is part of the omniORB library//// The omniORB library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library 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// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA////// Description:// *** PROPRIETORY INTERFACE ***// /* $Log: SocketCollection.cc,v $ Revision 1.1.2.26 2005/03/10 11:28:29 dgrisby Race condition between setSelectable / clearSelectable. Revision 1.1.2.25 2004/10/17 20:14:32 dgrisby Updated support for OpenVMS. Many thanks to Bruce Visscher. Revision 1.1.2.24 2004/09/13 15:31:09 dgrisby Really dumb problem with SocketCollection on Win32. Revision 1.1.2.23 2004/09/13 09:44:16 dgrisby Avoid theoretical (?) problem with socket limit on Windows. Revision 1.1.2.22 2004/08/31 14:59:09 dgrisby Don't bother calculating fd count on Windows because it ignores it. Revision 1.1.2.21 2004/08/17 14:59:47 dgrisby New selectable socket limit was wrong on Windows. Revision 1.1.2.20 2004/04/19 09:29:40 dgrisby Only close pipes if they were opened successfully. Revision 1.1.2.19 2004/04/08 10:02:20 dgrisby In thread pool mode, close connections that will not be selectable. Revision 1.1.2.18 2004/03/26 11:52:07 dgrisby SetHandleInformation not supported on ETS. Revision 1.1.2.17 2003/11/12 16:57:49 dgrisby Mistake in Windows case. Revision 1.1.2.16 2003/11/12 16:04:17 dgrisby Set sockets to close on exec. Revision 1.1.2.15 2003/07/25 16:04:57 dgrisby vxWorks patches. Revision 1.1.2.14 2003/02/17 10:39:52 dgrisby Fix inevitable Windows problem. Revision 1.1.2.13 2003/02/17 01:46:23 dgrisby Pipe to kick select thread (on Unix). Revision 1.1.2.12 2003/01/28 12:17:09 dgrisby Bug with Select() ignoring data in buffer indications. Revision 1.1.2.11 2002/10/14 15:27:41 dgrisby Typo in fcntl error check. Revision 1.1.2.10 2002/08/21 06:23:15 dgrisby Properly clean up bidir connections and ropes. Other small tweaks. Revision 1.1.2.9 2002/03/18 16:50:18 dpg1 New threadPoolWatchConnection parameter. Revision 1.1.2.8 2002/03/14 12:21:49 dpg1 Undo accidental scavenger period change, remove invalid assertion. Revision 1.1.2.7 2002/03/13 16:05:38 dpg1 Transport shutdown fixes. Reference count SocketCollections to avoid connections using them after they are deleted. Properly close connections when in thread pool mode. Revision 1.1.2.6 2002/02/26 14:06:45 dpg1 Recent changes broke Windows. Revision 1.1.2.5 2002/02/13 16:02:38 dpg1 Stability fixes thanks to Bastiaan Bakker, plus threading optimisations inspired by investigating Bastiaan's bug reports. Revision 1.1.2.4 2001/08/24 15:56:44 sll Fixed code which made the wrong assumption about the semantics of do { ...; continue; } while(0) Revision 1.1.2.3 2001/08/02 13:00:53 sll Do not use select(0,0,0,0,&timeout), it doesn't work on win32. Revision 1.1.2.2 2001/08/01 15:56:07 sll Workaround MSVC++ bug. It generates wrong code with FD_ISSET and FD_SET under certain conditions. Revision 1.1.2.1 2001/07/31 16:16:26 sll New transport interface to support the monitoring of active connections.*/#include <omniORB4/CORBA.h>#include <omniORB4/giopEndpoint.h>#include <SocketCollection.h>#if defined(__vxWorks__)# include "pipeDrv.h"# include "selectLib.h"# include "iostream.h"#endif#if defined(__VMS)# include <stropts.h>#endif#if !defined(__WIN32__)# define SELECTABLE_FD_LIMIT FD_SETSIZE#endifOMNI_NAMESPACE_BEGIN(omni)#define GDB_DEBUG/////////////////////////////////////////////////////////////////////////voidSocketSetTimeOut(unsigned long abs_sec, unsigned long abs_nsec,struct timeval& t){ unsigned long now_sec, now_nsec; omni_thread::get_time(&now_sec,&now_nsec); if ((abs_sec <= now_sec) && ((abs_sec < now_sec) || (abs_nsec < now_nsec))) { t.tv_sec = t.tv_usec = 0; } else { t.tv_sec = abs_sec - now_sec; if (abs_nsec >= now_nsec) { t.tv_usec = (abs_nsec - now_nsec) / 1000; } else { t.tv_usec = (1000000000 + abs_nsec - now_nsec) / 1000; t.tv_sec -= 1; } }}/////////////////////////////////////////////////////////////////////////intSocketSetnonblocking(SocketHandle_t sock) {# if defined(__vxWorks__) int fl = TRUE; if (ioctl(sock, FIONBIO, (int)&fl) == ERROR) { return RC_INVALID_SOCKET; } return 0;# elif defined(__VMS) int fl = 1; if (ioctl(sock, FIONBIO, &fl) == RC_INVALID_SOCKET) { return RC_INVALID_SOCKET; } return 0;# elif defined(__WIN32__) u_long v = 1; if (ioctlsocket(sock,FIONBIO,&v) == RC_SOCKET_ERROR) { return RC_INVALID_SOCKET; } return 0;# else int fl = O_NONBLOCK; if (fcntl(sock,F_SETFL,fl) == RC_SOCKET_ERROR) { return RC_INVALID_SOCKET; } return 0;# endif}/////////////////////////////////////////////////////////////////////////intSocketSetblocking(SocketHandle_t sock) {# if defined(__vxWorks__) int fl = FALSE; if (ioctl(sock, FIONBIO, (int)&fl) == ERROR) { return RC_INVALID_SOCKET; } return 0;# elif defined(__VMS) int fl = 0; if (ioctl(sock, FIONBIO, &fl) == RC_INVALID_SOCKET) { return RC_INVALID_SOCKET; } return 0;# elif defined(__WIN32__) u_long v = 0; if (ioctlsocket(sock,FIONBIO,&v) == RC_SOCKET_ERROR) { return RC_INVALID_SOCKET; } return 0;# else int fl = 0; if (fcntl(sock,F_SETFL,fl) == RC_SOCKET_ERROR) { return RC_INVALID_SOCKET; } return 0;# endif}/////////////////////////////////////////////////////////////////////////intSocketSetCloseOnExec(SocketHandle_t sock) {# if defined(__vxWorks__) || defined(__ETS_KERNEL__) // Not supported on vxWorks or ETS return 0;# elif defined(__WIN32__) SetHandleInformation((HANDLE)sock, HANDLE_FLAG_INHERIT, 0); return 0;# else int fl = FD_CLOEXEC; if (fcntl(sock,F_SETFD,fl) == RC_SOCKET_ERROR) { return RC_INVALID_SOCKET; } return 0;# endif}/////////////////////////////////////////////////////////////////////////unsigned long SocketCollection::scan_interval_sec = 0;unsigned long SocketCollection::scan_interval_nsec = 50*1000*1000;CORBA::ULong SocketCollection::hashsize = 103;/////////////////////////////////////////////////////////////////////////SocketCollection::SocketCollection() : pd_n_fdset_1(0), pd_n_fdset_2(0), pd_n_fdset_dib(0), pd_select_cond(&pd_fdset_lock), pd_abs_sec(0), pd_abs_nsec(0), pd_pipe_read(-1), pd_pipe_write(-1), pd_pipe_full(0), pd_refcount(1){ FD_ZERO(&pd_fdset_1); FD_ZERO(&pd_fdset_2); FD_ZERO(&pd_fdset_dib);#ifdef UnixArchitecture# ifdef __vxWorks__ if (pipeDrv() == OK) { if (pipeDevCreate("/pipe/SocketCollection",10,sizeof(int)) == OK) { pd_pipe_read = pd_pipe_write = open("/pipe/SocketCollection", O_RDWR,0); } } if (pd_pipe_read <= 0) { omniORB::logs(5, "Unable to create pipe for SocketCollection."); }# else int filedes[2]; int r = pipe(filedes); if (r != -1) { pd_pipe_read = filedes[0]; pd_pipe_write = filedes[1]; } else { omniORB::logs(5, "Unable to create pipe for SocketCollection."); }# endif#endif if (pd_pipe_read > 0) { pd_n_fdset_1++; pd_n_fdset_2++; FD_SET(pd_pipe_read, &pd_fdset_1); FD_SET(pd_pipe_read, &pd_fdset_2); } pd_hash_table = new SocketLink* [hashsize]; for (CORBA::ULong i=0; i < hashsize; i++) pd_hash_table[i] = 0;}/////////////////////////////////////////////////////////////////////////SocketCollection::~SocketCollection(){ pd_refcount = -1; delete [] pd_hash_table;#ifdef UnixArchitecture# ifdef __vxWorks__ // *** How do we clean up on vxWorks?# else if (pd_pipe_read > 0) close(pd_pipe_read); if (pd_pipe_write > 0) close(pd_pipe_write);# endif#endif}/////////////////////////////////////////////////////////////////////////voidSocketCollection::setSelectable(SocketHandle_t sock, int now, CORBA::Boolean data_in_buffer, CORBA::Boolean hold_lock) {#ifdef SELECTABLE_FD_LIMIT if (sock >= SELECTABLE_FD_LIMIT) return;#endif omni_optional_lock l(pd_fdset_lock, hold_lock, hold_lock); if (data_in_buffer && !FD_ISSET(sock,&pd_fdset_dib)) { pd_n_fdset_dib++; FD_SET(sock,&pd_fdset_dib); } if (!FD_ISSET(sock,&pd_fdset_1)) { if (now == 2) { return; } pd_n_fdset_1++; FD_SET(sock,&pd_fdset_1); } if (now || data_in_buffer) { if (!FD_ISSET(sock,&pd_fdset_2)) { pd_n_fdset_2++; FD_SET(sock,&pd_fdset_2); } // Wake up the thread blocked in select() if we can. if (pd_pipe_write > 0) {#ifdef UnixArchitecture if (!pd_pipe_full) { char data = '\0'; pd_pipe_full = 1; write(pd_pipe_write, &data, 1); }#endif } else { pd_select_cond.signal(); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?