//============================================================================ // TSocketClient::ExecuteCustom : Execute a custom client test. //---------------------------------------------------------------------------- void TSocketClient::ExecuteCustom(bool *isDone, UInt16 thePort) { UInt32 n, theValue; NSocket *theSocket; NStatus theErr; // Open the socket theSocket = new NSocket(this); theSocket->Open("127.0.0.1", thePort); while (theSocket->GetStatus() != kNSocketOpened) NThread::Sleep(); // Get/set optins theErr = theSocket->SetOption(kNSocketNoDelay, (SInt32) true); NN_ASSERT_NOERR(theErr); theValue = theSocket->GetOption(kNSocketNoDelay); NN_ASSERT(theValue == (SInt32) true); // Write some data for (n = 0; n < kTestNumItems; n++) { theErr = theSocket->WriteUInt32(n); NN_ASSERT_NOERR(theErr); } // Read the response for (n = 0; n < kTestNumItems; n++) { theErr = theSocket->ReadUInt32(theValue); NN_ASSERT_NOERR(theErr); NN_ASSERT(theValue == (n * n)); } // Clean up theSocket->Close(); while (theSocket->GetStatus() != kNSocketClosed) NThread::Sleep(); delete theSocket; // Finish off *isDone = true; }
//============================================================================ // NDBHandlePool::Open : Open the database. //---------------------------------------------------------------------------- NStatus NDBHandlePool::Open(const NFile &theFile, NDBFlags theFlags, const NString &theVFS) { NDBHandlePtr dbHandle; NStatus theErr; // Validate our parameters and state NN_ASSERT(theFile.IsValid()); NN_ASSERT(!IsOpen()); // Update our state mFile = theFile; mFlags = theFlags; mVFS = theVFS; // Create the initial connection // // The initial connection allows us to test that we can actually open the // database, and may be all that we need if we're only to connect once. theErr = CreateConnection(dbHandle); NN_ASSERT_NOERR(theErr); mIsOpen = (dbHandle != NULL); if (mIsOpen) mPool.PushBack(dbHandle); return(theErr); }
//============================================================================ // NTask::Execute : Execute the task. //---------------------------------------------------------------------------- NString NTask::Execute(NTime waitFor) { NString theResult; NTime endTime; NStatus theErr; // Get the state we need endTime = NTimeUtilities::GetTime() + waitFor; // Execute the command theErr = Launch(); NN_ASSERT_NOERR(theErr); // Wait for the results while (IsRunning()) { if (waitFor >= kNTimeNone && NTimeUtilities::GetTime() >= endTime) break; UpdateTask(kTaskSleep); } theResult = ReadOutput() + ReadError(); return(theResult); }
//============================================================================ // NDBHandlePool::CreateConnection : Create a connection. //---------------------------------------------------------------------------- NStatus NDBHandlePool::CreateConnection(NDBHandlePtr &dbHandle) { NStatus theErr; // Create the connection dbHandle = new NDBHandle; theErr = dbHandle->Open(mFile, mFlags, mVFS); NN_ASSERT_NOERR(theErr); // Apply the connector if (theErr == kNoErr && mConnector != NULL) mConnector(*dbHandle); // Handle failure if (theErr != kNoErr) { delete dbHandle; dbHandle = NULL; } return(theErr); }
//============================================================================ // NFileUtilities::SetFileData : Set a file to data. //---------------------------------------------------------------------------- NStatus NFileUtilities::SetFileData(const NFile &theFile, const NData &theData) { uint64_t theSize, numWritten; NFile mutableFile; NStatus theErr; // Get the state we need mutableFile = theFile; theSize = theData.GetSize(); // Open the file theErr = mutableFile.Open(kNPermissionUpdate, true); if (theErr != kNoErr) return(theErr); // Write the data theErr = mutableFile.SetSize(0); theErr |= mutableFile.Write(theSize, theData.GetData(), numWritten); NN_ASSERT_NOERR(theErr); NN_ASSERT(numWritten == theSize); // Clean up mutableFile.Close(); return(theErr); }
//============================================================================ // NTargetThread::LocalSetValue : Set a thread-local value. //---------------------------------------------------------------------------- void NTargetThread::LocalSetValue(NThreadLocalRef theKey, void *theValue) { pthread_key_t keyRef = (pthread_key_t) theKey; int sysErr; // Set the value sysErr = pthread_setspecific(keyRef, theValue); NN_ASSERT_NOERR(sysErr); }
//============================================================================ // NTargetThread::LocalDestroy : Destroy a thread-local value. //---------------------------------------------------------------------------- void NTargetThread::LocalDestroy(NThreadLocalRef theKey) { pthread_key_t keyRef = (pthread_key_t) theKey; int sysErr; // Destroy the key sysErr = pthread_key_delete(keyRef); NN_ASSERT_NOERR(sysErr); }
//============================================================================ // NTargetThread::SemaphoreSignal : Signal a semaphore. //---------------------------------------------------------------------------- void NTargetThread::SemaphoreSignal(NSemaphoreRef theSemaphore) { sem_t *semRef = (sem_t *) theSemaphore; int sysErr; // Signal the semaphore sysErr = sem_post(semRef); NN_ASSERT_NOERR(sysErr); }
//============================================================================ // TSocketClient::ExecuteWeb : Execute a web client test. //---------------------------------------------------------------------------- void TSocketClient::ExecuteWeb(bool *isDone, NData *theData) { NSocket *theSocket; NString theText; NStatus theErr; // Open the socket theSocket = new NSocket(this); theSocket->Open("www.google.com", 80); while (theSocket->GetStatus() != kNSocketOpened) NThread::Sleep(); // Write some data theText = "GET / HTTP/1.0\r\n\r\n"; theErr = theSocket->WriteData(theText.GetData()); NN_ASSERT_NOERR(theErr); // Read some data theErr = theSocket->ReadData(400, *theData); NN_ASSERT_NOERR(theErr); // Clean up theSocket->Close(); while (theSocket->GetStatus() != kNSocketClosed) NThread::Sleep(); delete theSocket; // Finish off *isDone = true; }
//============================================================================ // NDBHandlePool::ExecuteData : Execute a query to obtain data. //---------------------------------------------------------------------------- NData NDBHandlePool::ExecuteData(const NDBQuery &theQuery) { NData theValue; NStatus theErr; // Execute the query theErr = Execute(theQuery, BindFunction(NDBResult::GetRowValueData, kNArg1, 0, &theValue)); NN_ASSERT_NOERR(theErr); return(theValue); }
//============================================================================ // NTargetThread::SemaphoreDestroy : Destroy a semaphore. //---------------------------------------------------------------------------- void NTargetThread::SemaphoreDestroy(NSemaphoreRef theSemaphore) { sem_t *semRef = (sem_t *) theSemaphore; int sysErr; // Destroy the semaphore sysErr = sem_destroy(semRef); NN_ASSERT_NOERR(sysErr); free(semRef); }
//============================================================================ // NTargetThread::SemaphoreCreate : Create a semaphore. //---------------------------------------------------------------------------- NSemaphoreRef NTargetThread::SemaphoreCreate(NIndex theValue) { sem_t *semRef; int sysErr; // Create the semaphore semRef = (sem_t *) malloc(sizeof(sem_t)); sysErr = sem_init(semRef, 0, theValue); NN_ASSERT_NOERR(sysErr); return((NSemaphoreRef) semRef); }
//============================================================================ // NDBHandlePool::ExecuteFloat64 : Execute a query to obtain a float64_t. //---------------------------------------------------------------------------- float64_t NDBHandlePool::ExecuteFloat64(const NDBQuery &theQuery) { float64_t theValue; NStatus theErr; // Execute the query theValue = 0.0; theErr = Execute(theQuery, BindFunction(NDBResult::GetRowValueFloat64, kNArg1, 0, &theValue)); NN_ASSERT_NOERR(theErr); return(theValue); }
//============================================================================ // TSocketServer::HandleConnection : Handle a connection. //---------------------------------------------------------------------------- void TSocketServer::HandleConnection(NSocket *theSocket) { UInt32 n, theValue; NStatus theErr; // Read the incoming data for (n = 0; n < kTestNumItems; n++) { theErr = theSocket->ReadUInt32(theValue); NN_ASSERT_NOERR(theErr); NN_ASSERT(theValue == n); } // Send a response for (n = 0; n < kTestNumItems; n++) { theErr = theSocket->WriteUInt32(n * n); NN_ASSERT_NOERR(theErr); } }
//============================================================================ // NFileUtilities::GetFileData : Get a file as data. //---------------------------------------------------------------------------- NData NFileUtilities::GetFileData(const NFile &theFile) { uint64_t theSize, numRead; NFile mutableFile; NData theData; NStatus theErr; // Get the state we need mutableFile = theFile; theSize = mutableFile.GetSize(); NN_ASSERT( ((int64_t) theSize) <= kInt32Max); // Resize the buffer if (!theData.SetSize((NIndex) theSize)) return(theData); // Open the file theErr = mutableFile.Open(); if (theErr != kNoErr) { theData.Clear(); return(theData); } // Read the data theErr = mutableFile.Read(theSize, theData.GetData(), numRead); theData.SetSize((NIndex) numRead); NN_ASSERT_NOERR(theErr); NN_ASSERT(numRead == theSize); NN_ASSERT(((int64_t) numRead) <= kInt32Max); // Clean up mutableFile.Close(); return(theData); }
//============================================================================ // NDBHandlePool::AcquireConnection : Acquire a connection. //---------------------------------------------------------------------------- bool NDBHandlePool::AcquireConnection(NDBHandlePtr &dbHandle) { NStatus theErr; // Validate our state NN_ASSERT(mIsOpen); // Acquire a single connection // // A pool always starts with one connection, so we can block until we // are able to acquire the lock and extract this connection. // // The list will be unlocked when we release the connection, allowing // one of any of the threads then blocked on the lock to continue. if (mFlags & kNDBPoolConnectOnce) { mPool.Lock(); dbHandle = mPool.GetValue(0); NN_ASSERT(dbHandle != NULL); } // Acquire one of multiple connections // // Connections are created on demand, with no cap (the assumption is that // the number of threads acquiring connections will be capped externally // via an NThreadPool or similar). // // Newly created connections are owned by the caller, so will be added to // the pool when that connection is eventually released. else { if (!mPool.PopFront(dbHandle)) { theErr = CreateConnection(dbHandle); NN_ASSERT_NOERR(theErr); } } return(dbHandle != NULL); }
//============================================================================ // NTargetThread::ThreadCreate : Create a thread. //---------------------------------------------------------------------------- NStatus NTargetThread::ThreadCreate(const NFunctor &theFunctor) { NFunctor *tmpFunctor; pthread_t threadID; int sysErr; // Get the state we need tmpFunctor = new NFunctor(theFunctor); // Create the thread sysErr = pthread_create(&threadID, NULL, ThreadEntry, tmpFunctor); NN_ASSERT_NOERR(sysErr); return(NLinuxTarget::ConvertSysErr(sysErr)); }
//============================================================================ // NTargetThread::LocalCreate : Create a thread-local value. //---------------------------------------------------------------------------- NThreadLocalRef NTargetThread::LocalCreate(void) { pthread_key_t keyRef; int sysErr; // Validate our state NN_ASSERT(sizeof(pthread_key_t) <= sizeof(NThreadLocalRef)); // Create the key keyRef = 0; sysErr = pthread_key_create(&keyRef, NULL); NN_ASSERT_NOERR(sysErr); return((NThreadLocalRef) keyRef); }
//============================================================================ // NTargetNetwork::SocketOpen : Open a socket. //---------------------------------------------------------------------------- NSocketRef NTargetNetwork::SocketOpen(NSocket *nanoSocket, const NString &theHost, uint16_t thePort) { struct addrinfo *theAddress, *addrList; int sysErr, tmpSocket; NSocketRef theSocket; const char *hostName; struct addrinfo addrInfo; bool isListen; NString portNum; // Get the state we need isListen = theHost.IsEmpty(); theAddress = NULL; hostName = isListen ? NULL : theHost.GetUTF8(); portNum.Format("%d",thePort); // Create the address memset(&addrInfo, 0, sizeof(struct addrinfo)); addrInfo.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 addrInfo.ai_socktype = SOCK_STREAM; // Always TCP addrInfo.ai_flags = isListen ? AI_PASSIVE : 0; sysErr = getaddrinfo(hostName, portNum.GetUTF8(), &addrInfo, &addrList); NN_ASSERT_NOERR(sysErr); if (sysErr != 0) return(NULL); // Create the socket // // As we may have multiple addresses, we loop until we find one that we can connect/bind. for (theAddress = addrList; theAddress != NULL; theAddress = theAddress->ai_next) { tmpSocket = socket(theAddress->ai_family, theAddress->ai_socktype, theAddress->ai_protocol); if (tmpSocket == kSocketHandleInvalid) continue; if (isListen) { if (bind(tmpSocket, theAddress->ai_addr, theAddress->ai_addrlen) == 0) break; } else { if (connect(tmpSocket, theAddress->ai_addr, theAddress->ai_addrlen) == 0) break; } close(tmpSocket); } freeaddrinfo(addrList); NN_ASSERT(theAddress != NULL); if (theAddress == NULL) return(NULL); // Setup signal handler for closed sockets // // TO DO /* sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; NN_ASSERT(sigaction(SIGCHLD, &sa, NULL) != -1); */ // TODO Create thread for listening/accepting connections // Create the socket info theSocket = new NSocketInfo; theSocket->nanoSocket = nanoSocket; theSocket->nativeSocket = tmpSocket; return(theSocket); }