1 /*
   2  * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores,
  20  * CA 94065 USA or visit www.oracle.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 #include <assert.h>
  26 #include "serverLists.hpp"
  27 
  28 //----------------------------------------------------------------------
  29 // Lists
  30 //
  31 
  32 CRITICAL_SECTION Lists::crit;
  33 
  34 void
  35 Lists::init() {
  36   InitializeCriticalSection(&crit);
  37 }
  38 
  39 void
  40 Lists::lock() {
  41   EnterCriticalSection(&crit);
  42 }
  43 
  44 void
  45 Lists::unlock() {
  46   LeaveCriticalSection(&crit);
  47 }
  48 
  49 //----------------------------------------------------------------------
  50 // ListsLocker
  51 //
  52 
  53 ListsLocker::ListsLocker() {
  54   Lists::lock();
  55 }
  56 
  57 ListsLocker::~ListsLocker() {
  58   Lists::unlock();
  59 }
  60 
  61 //----------------------------------------------------------------------
  62 // ChildInfo
  63 //
  64 
  65 ChildInfo::ChildInfo(DWORD pid, HANDLE childProcessHandle,
  66                      HANDLE writeToStdinHandle, HANDLE readFromStdoutHandle,
  67                      HANDLE auxHandle1, HANDLE auxHandle2) {
  68   this->pid = pid;
  69   this->childProcessHandle = childProcessHandle;
  70   this->writeToStdinHandle = writeToStdinHandle;
  71   this->readFromStdoutHandle = readFromStdoutHandle;
  72   this->auxHandle1 = auxHandle1;
  73   this->auxHandle2 = auxHandle2;
  74   client = NULL;
  75 }
  76 
  77 DWORD
  78 ChildInfo::getPid() {
  79   return pid;
  80 }
  81 
  82 HANDLE
  83 ChildInfo::getChildProcessHandle() {
  84   return childProcessHandle;
  85 }
  86 
  87 HANDLE
  88 ChildInfo::getWriteToStdinHandle() {
  89   return writeToStdinHandle;
  90 }
  91 
  92 HANDLE
  93 ChildInfo::getReadFromStdoutHandle() {
  94   return readFromStdoutHandle;
  95 }
  96 
  97 void
  98 ChildInfo::setClient(ClientInfo* clientInfo) {
  99   client = clientInfo;
 100 }
 101 
 102 ClientInfo*
 103 ChildInfo::getClient() {
 104   return client;
 105 }
 106 
 107 void
 108 ChildInfo::closeAll() {
 109   CloseHandle(childProcessHandle);
 110   CloseHandle(writeToStdinHandle);
 111   CloseHandle(readFromStdoutHandle);
 112   CloseHandle(auxHandle1);
 113   CloseHandle(auxHandle2);
 114 }
 115 
 116 //----------------------------------------------------------------------
 117 // ChildList
 118 //
 119 
 120 ChildList::ChildList() {
 121 }
 122 
 123 ChildList::~ChildList() {
 124 }
 125 
 126 void
 127 ChildList::addChild(ChildInfo* info) {
 128   // Could store these in binary sorted order by pid for efficiency
 129   childList.push_back(info);
 130 }
 131 
 132 ChildInfo*
 133 ChildList::removeChild(HANDLE childProcessHandle) {
 134   for (ChildInfoList::iterator iter = childList.begin(); iter != childList.end();
 135        iter++) {
 136     ChildInfo* info = *iter;
 137     if (info->getChildProcessHandle() == childProcessHandle) {
 138       childList.erase(iter);
 139       return info;
 140     }
 141   }
 142   assert(false);
 143   return NULL;
 144 }
 145 
 146 void
 147 ChildList::removeChild(ChildInfo* info) {
 148   for (ChildInfoList::iterator iter = childList.begin(); iter != childList.end();
 149        iter++) {
 150     if (*iter == info) {
 151       childList.erase(iter);
 152       return;
 153     }
 154   }
 155   assert(false);
 156 }
 157 
 158 ChildInfo*
 159 ChildList::getChildByPid(DWORD pid) {
 160   for (ChildInfoList::iterator iter = childList.begin(); iter != childList.end();
 161        iter++) {
 162     ChildInfo* info = *iter;
 163     if (info->getPid() == pid) {
 164       return info;
 165     }
 166   }
 167   return NULL;
 168 }
 169 
 170 int
 171 ChildList::size() {
 172   return childList.size();
 173 }
 174 
 175 ChildInfo*
 176 ChildList::getChildByIndex(int index) {
 177   return childList[index];
 178 }
 179 
 180 //----------------------------------------------------------------------
 181 // ClientInfo
 182 //
 183 
 184 ClientInfo::ClientInfo(SOCKET dataSocket) {
 185   this->dataSocket = dataSocket;
 186   buf = new IOBuf(32768, 131072);
 187   buf->setSocket(dataSocket);
 188   target = NULL;
 189 }
 190 
 191 ClientInfo::~ClientInfo() {
 192   delete buf;
 193 }
 194 
 195 SOCKET
 196 ClientInfo::getDataSocket() {
 197   return dataSocket;
 198 }
 199 
 200 IOBuf*
 201 ClientInfo::getIOBuf() {
 202   return buf;
 203 }
 204 
 205 void
 206 ClientInfo::setTarget(ChildInfo* childInfo) {
 207   target = childInfo;
 208 }
 209 
 210 ChildInfo*
 211 ClientInfo::getTarget() {
 212   return target;
 213 }
 214 
 215 void
 216 ClientInfo::closeAll() {
 217   shutdown(dataSocket, SD_BOTH);
 218   closesocket(dataSocket);
 219   dataSocket = INVALID_SOCKET;
 220 }
 221 
 222 //----------------------------------------------------------------------
 223 // ClientList
 224 //
 225 
 226 ClientList::ClientList() {
 227 }
 228 
 229 ClientList::~ClientList() {
 230 }
 231 
 232 void
 233 ClientList::addClient(ClientInfo* info) {
 234   clientList.push_back(info);
 235 }
 236 
 237 bool
 238 ClientList::isAnyDataSocketSet(fd_set* fds, ClientInfo** out) {
 239   for (ClientInfoList::iterator iter = clientList.begin(); iter != clientList.end();
 240        iter++) {
 241     ClientInfo* info = *iter;
 242     if (FD_ISSET(info->getDataSocket(), fds)) {
 243       *out = info;
 244       return true;
 245     }
 246   }
 247   return false;
 248 }
 249 
 250 void
 251 ClientList::removeClient(ClientInfo* client) {
 252   for (ClientInfoList::iterator iter = clientList.begin(); iter != clientList.end();
 253        iter++) {
 254     if (*iter == client) {
 255       clientList.erase(iter);
 256       return;
 257     }
 258   }
 259   assert(false);
 260 }
 261 
 262 int
 263 ClientList::size() {
 264   return clientList.size();
 265 }
 266 
 267 ClientInfo*
 268 ClientList::get(int num) {
 269   return clientList[num];
 270 }