📄 ccache_hash.c
字号:
int theHKey; char errorReply[SERV_REPLY_LENGTH]; /* Start by looking at the oldest connection. */ locSockRec = TimeOutListOld; /* Search the list for the oldest inactive connection. */ while ((locSockRec != NULL) && (locSockRec->sockStateStor != INACTIVE)) locSockRec = locSockRec->listPrev; /* If we didn't find one, all are active. */ if (locSockRec == NULL) return FALSE; /* Strip it from the expiration list. */ if (locSockRec->listNext == NULL) TimeOutListOld = locSockRec->listPrev; else locSockRec->listNext->listPrev = locSockRec->listPrev; if (locSockRec->listPrev == NULL) TimeOutListNew = locSockRec->listNext; else locSockRec->listPrev->listNext = locSockRec->listNext; /* Strip it from the active hash. */ theHKey = GetHKey(locSockRec->theHostIP); if (locSockRec->hashPrev == NULL) { SockHash[theHKey] = locSockRec->hashNext; if (SockHash[theHKey] != NULL) SockHash[theHKey]->hashPrev = NULL; } else locSockRec->hashPrev->hashNext = locSockRec->hashNext; if (locSockRec->hashNext != NULL) locSockRec->hashNext->hashPrev = locSockRec->hashPrev; /* Disconnect the socket. */ CancelTimer(locSockRec->timerid); /* Cancel the timer. */ Disconnect(locSockRec->theSocket, errorReply); free_url(locSockRec->socketInfo); free((char *) locSockRec); return TRUE;}/**************************************************************************** function: TouchDate()**** parameters: A record to update.**** postconditions: Last access time field is updated and this connection** is moved to the front of the expiration list.***************************************************************************/static void TouchDate(SockCntlRec * theRec){ /* If it's already first don't need to move it. */ if (theRec == TimeOutListNew) return; /* Move it to the front of the list. */ theRec->listPrev->listNext = theRec->listNext; if (theRec->listNext != NULL) theRec->listNext->listPrev = theRec->listPrev; if (theRec == TimeOutListOld) TimeOutListOld = theRec->listPrev; theRec->listPrev = NULL; theRec->listNext = TimeOutListNew; TimeOutListNew->listPrev = theRec; TimeOutListNew = theRec; CancelTimer(theRec->timerid); theRec->timerid = SetTimer(timeOut, ExpireSocket);}/************************************************************************ function: SockRetrieve()**** parameters: An allocated URL and the way the returned data is to ** be buffered.**** postconditions: A new SockCntlRec will be returned, which will either** represent a new one or a preopened connection.***********************************************************************/static SockCntlRec *SockRetrieve(URL * theURL, BufferStatus sockRetrType){ unsigned long theIPnum; unsigned int theHKey; SockCntlRec *newSock; URL *newURL; /* If invalid data or not initialized, just return a NULL. */ if (theURL == NULL) return (NULL); if (!initialized) SockInit(NULL); /*Get the IP of the host we're looking for. */ if ((theIPnum = gethostinhex(theURL->host)) == -1) return (NULL); DoError(NO_ERROR, NULL); /* Find the hash bucket to look in. */ theHKey = GetHKey(theIPnum); /* Try to find a connection in that bucket. */ newSock = SearchList(SockHash[theHKey], theURL); if (newSock != (NULL)) { /* Move to front of list and update time. */ TouchDate(newSock); newSock->sockStateStor = sockRetrType; return (newSock); } /* Need to open a new conection. */ /* If we are already at the maxConnections, try and disconnect one. */ if (currConnections == maxConnections) { if (!DisconnectOne()) return (NULL); } /* Get a new connnection. */ newURL = dup_url(theURL); /* save a copy */ newSock = GetConnection(newURL, theIPnum); if (newSock == NULL) return (NULL); /* Set it up. */ newSock->sockStateStor = sockRetrType; newSock->hashPrev = NULL; newSock->hashNext = SockHash[theHKey]; if (SockHash[theHKey] != NULL) SockHash[theHKey]->hashPrev = newSock; SockHash[theHKey] = newSock; newSock->listPrev = NULL; newSock->listNext = TimeOutListNew; if (TimeOutListNew != NULL) TimeOutListNew->listPrev = newSock; else TimeOutListOld = newSock; TimeOutListNew = newSock; return (newSock);}/*************************************************************************** function: SockGetData()**** parameters: Need a URL struct parsed by liburl and return string for** fetched filename dcm 6/28/94**** postcondition: Data is returned as requested if possible.**************************************************************************/DataReturn *SockGetData(URL * myURL, BufferStatus theStatus, char *filename){ SockCntlRec *mySocket; DataReturn *myDataReturn; int errNum; char errorReply[SERV_REPLY_LENGTH]; if (!initialized) SockInit(NULL); /* If not an FTP url, then we can't ftp anything. */ if (myURL->type != URL_FTP) { DoError(BAD_URL_TYPE, NULL); return NULL; } /* Get a socket. */ Freeze(); mySocket = SockRetrieve(myURL, theStatus); Thaw(); if (!mySocket) return NULL; if (GetError() != noErr) { mySocket->sockStateStor = INACTIVE; return NULL; } myDataReturn = (DataReturn *) malloc(sizeof(DataReturn)); /* Set flags for FTP layer. */ if (theStatus == MEMORY_ONLY) { myDataReturn->inMemory = TRUE; myDataReturn->useTempFile = FALSE; } else { myDataReturn->inMemory = FALSE; if (theStatus == TEMP) myDataReturn->useTempFile = TRUE; else if (filename == NULL) { myDataReturn->useTempFile = FALSE; StripFileName(myDataReturn->fileName, myURL->pathname); } else { myDataReturn->useTempFile = FALSE; strcpy(myDataReturn->fileName, filename); } } /* Try to retrieve the requested file. */ errNum = Retrieve(myURL->pathname + 1, mySocket->theSocket, NULL, FALSE, TRUE, errorReply, myDataReturn); mySocket->sockStateStor = INACTIVE; if (errNum < 0) { if (errNum == SERV_REPLY_ERROR) DoError(errNum, errorReply); else DoError(errNum, NULL); DestroyDataReturn(myDataReturn); return (NULL); } return (myDataReturn);}/******************************************************************************** function name: ExpireSocket()**** preconditions: A timer must have already been set for this socket.** The whichTimer should identify the socket to be expired.**** postconditions: The socket is expired and the connection is closed.********************************************************************************/int ExpireSocket(int whichTimer){ SockCntlRec *locSockRec; int theHKey; char errorReply[SERV_REPLY_LENGTH]; if (!initialized) return 1; locSockRec = TimeOutListOld; /* Try to find the correct socket. */ while ((locSockRec != NULL) && (locSockRec->timerid != whichTimer)) locSockRec = locSockRec->listPrev; if (locSockRec == NULL) return 1; /* If it's still being used reset the timer. */ if (locSockRec->sockStateStor != INACTIVE) { locSockRec->timerid = SetTimer(timeOut, ExpireSocket); return 1; } /* Strip it from the expiration list. */ if (locSockRec->listNext == NULL) TimeOutListOld = locSockRec->listPrev; else locSockRec->listNext->listPrev = locSockRec->listPrev; if (locSockRec->listPrev == NULL) TimeOutListNew = locSockRec->listNext; else locSockRec->listPrev->listNext = locSockRec->listNext; /* Strip it from the active hash. */ theHKey = GetHKey(locSockRec->theHostIP); if (locSockRec->hashPrev == NULL) { SockHash[theHKey] = locSockRec->hashNext; if (SockHash[theHKey] != NULL) SockHash[theHKey]->hashPrev = NULL; } else locSockRec->hashPrev->hashNext = locSockRec->hashNext; if (locSockRec->hashNext != NULL) locSockRec->hashNext->hashPrev = locSockRec->hashPrev; /* Disconnect the socket. */ Disconnect(locSockRec->theSocket, errorReply); free_url(locSockRec->socketInfo); free((char *) locSockRec); return 1;}/******************************************************************************** function name: ShutDownCache()**** preconditions: The cache must have previously been initialized.**** postconditions: Timer's are all cleared, everything is disconnected.********************************************************************************/void ShutDownCache(){ if (!initialized) return; /* Freeze Timers and disconnect all sockets. */ Freeze(); while (DisconnectOne()); initialized = FALSE; free((char *) SockHash); /* Reset signals. */ signal(SIGALRM, NULL); signal(SIGUSR1, NULL); return;}/******************************************************************************** function name: DestroyDataReturn()**** preconditions: Need an allocated DataReturn.**** postconditions: Memory is freed.********************************************************************************/void DestroyDataReturn(theDataReturn) DataReturn *theDataReturn;{ free(theDataReturn->buffer); free(theDataReturn); theDataReturn = NULL;}/******************************************************************************** function name: DumpHash()**** preconditions: SIGUSR1 must be set up to call this function.**** postconditions: On a SIGUSR the hash tables internals are printed.********************************************************************************/static void DumpHash(){ int i; SockCntlRec *theSocket; /* * If we're not initialized for some reason, print out an * appropriate message. */ if (!initialized) { printf("Sorry, the hash table has not been initialized.\n"); printf("No data to output.\n"); return; } /* Go through the slots to find all connections. */ for (i = 0; i < HASH_SLOTS; i++) { /* If we find one, print out its stuff. */ if (SockHash[i] != NULL) { printf("Hash Slot %d:\n", i); theSocket = SockHash[i]; /* Print out ALL nodes in the linked list. */ while (theSocket != NULL) { printf("\t%s\n", theSocket->socketInfo->url); theSocket = theSocket->hashNext; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -