unsigned char *ReadBuffer::allocateBuffer(unsigned int newSize) { unsigned char *newBuffer = new unsigned char[newSize]; if (newBuffer == NULL) { #ifdef PANIC *logofs << "ReadBuffer: PANIC! Can't allocate " << newSize << " bytes of memory for buffer " << "in context [B].\n" << logofs_flush; #endif cerr << "Error" << ": Can't allocate memory for " << "read buffer in context [B].\n"; HandleCleanup(); } #ifdef VALGRIND memset(newBuffer, '\0', newSize); #endif return newBuffer; }
int GenericChannel::handleCompletion(EncodeBuffer &encodeBuffer) { // // Add the bits telling to the remote // that all data in the frame has been // encoded. // if (encodeBuffer.getLength() > 0) { #if defined(TEST) || defined(INFO) *logofs << "handleCompletion: Writing completion bits with " << encodeBuffer.getLength() << " bytes encoded " << "for FD#" << fd_ << ".\n" << logofs_flush; #endif encodeBuffer.encodeValue(0, 32, 14); return 1; } #if defined(TEST) || defined(INFO) else { *logofs << "handleCompletion: PANIC! No completion to write " << "for FD#" << fd_ << ".\n" << logofs_flush; HandleCleanup(); } #endif return 0; }
int IApp::Run(void) { SLOG(App_Run,SeverityInfo) << std::endl; // First set our Running flag to true mRunning = true; // Register our App pointer with our StatManager mStatManager.RegisterApp(this); // Register our App pointer with our StateManager mStateManager.RegisterApp(this); // First register the IAssetHandler derived classes in the GQE Core library mAssetManager.RegisterHandler(new(std::nothrow) ConfigHandler()); mAssetManager.RegisterHandler(new(std::nothrow) FontHandler()); mAssetManager.RegisterHandler(new(std::nothrow) ImageHandler()); mAssetManager.RegisterHandler(new(std::nothrow) MusicHandler()); mAssetManager.RegisterHandler(new(std::nothrow) SoundHandler()); // Give derived class a time to register custom IAssetHandler classes InitAssetHandlers(); // Attempt to open the application wide settings.cfg file as a ConfigAsset // registered under the ID of "resources/settings.cfg" InitSettingsConfig(); // Try to open the Renderer window to display graphics InitRenderer(); // Give the derived application a chance to register a IScreenFactory class // to provide IScreen derived classes (previously known as IState derived // classes) as requested. InitScreenFactory(); // Give the StatManager a chance to initialize mStatManager.DoInit(); // GameLoop if Running flag is still true GameLoop(); // Cleanup our application HandleCleanup(); // Perform our own internal Cleanup Cleanup(); // Make sure our Running flag is set to false before exiting mRunning = false; if(mExitCode < 0) SLOGR(App_Run,SeverityError) << "exitCode=" << mExitCode << std::endl; else SLOGR(App_Run,SeverityInfo) << "exitCode=" << mExitCode << std::endl; // Return the Exit Code specified by Quit or 0 of Quit was never called return mExitCode; }
void ReadBuffer::fullReset() { #ifdef TEST if (owner_ == 0) { *logofs << "ReadBuffer: PANIC! Class for FD#" << transport_ -> fd() << " doesn't " << "appear to be the owner of the buffer " << "in reset.\n" << logofs_flush; HandleCleanup(); } #endif if (length_ == 0 && size_ > maximumBufferSize_) { #ifdef TEST *logofs << "ReadBuffer: Resizing buffer for FD#" << transport_ -> fd() << " in reset from " << size_ << " to " << maximumBufferSize_ << " bytes.\n" << logofs_flush; #endif delete [] buffer_; int newSize = maximumBufferSize_; unsigned char *newBuffer = allocateBuffer(newSize); buffer_ = newBuffer; size_ = newSize; transport_ -> pendingReset(); owner_ = 1; start_ = 0; } }
void ClientStore::dumpSplitStores() const { for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++) { if (splits_[i] != NULL) { splits_[i] -> dump(); } } if ((getSplitTotalSize() != 0 && getSplitTotalStorageSize() == 0) || (getSplitTotalSize() == 0 && getSplitTotalStorageSize() != 0)) { #ifdef PANIC *logofs << "ClientStore: PANIC! Inconsistency detected " << "while handling the split stores.\n" << logofs_flush; #endif HandleCleanup(); } }
int GenericChannel::handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message, unsigned int length) { #ifdef TEST *logofs << "handleRead: Called for FD#" << fd_ << " with " << encodeBuffer.getLength() << " bytes already encoded.\n" << logofs_flush; #endif // // Pointer to located message and // its size in bytes. // const unsigned char *inputMessage; unsigned int inputLength; // // Tag message as generic data in compression // routine. Opcode is not actually transferred // over the network. // unsigned char inputOpcode = X_NXInternalGenericData; #if defined(TEST) || defined(INFO) *logofs << "handleRead: Trying to read from FD#" << fd_ << " at " << strMsTimestamp() << ".\n" << logofs_flush; #endif int result = readBuffer_.readMessage(); #ifdef DEBUG *logofs << "handleRead: Read result on FD#" << fd_ << " is " << result << ".\n" << logofs_flush; #endif if (result < 0) { // // Let the proxy close the channel. // return -1; } else if (result == 0) { #if defined(TEST) || defined(INFO) *logofs << "handleRead: PANIC! No data read from FD#" << fd_ << " while encoding messages.\n" << logofs_flush; HandleCleanup(); #endif return 0; } #if defined(TEST) || defined(INFO) || defined(FLUSH) *logofs << "handleRead: Encoding messages for FD#" << fd_ << " with " << readBuffer_.getLength() << " bytes " << "in the buffer.\n" << logofs_flush; #endif // // Divide the available data in multiple // messages and encode them one by one. // if (proxy -> handleAsyncSwitch(fd_) < 0) { return -1; } while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) { encodeBuffer.encodeValue(inputLength, 32, 14); if (isCompressed() == 1) { unsigned int compressedDataSize = 0; unsigned char *compressedData = NULL; if (handleCompress(encodeBuffer, inputOpcode, 0, inputMessage, inputLength, compressedData, compressedDataSize) < 0) { return -1; } } else { encodeBuffer.encodeMemory(inputMessage, inputLength); } int bits = encodeBuffer.diffBits(); #if defined(TEST) || defined(OPCODES) *logofs << "handleRead: Handled generic data for FD#" << fd_ << ". " << inputLength << " bytes in, " << bits << " bits (" << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush; #endif addProtocolBits(inputLength << 3, bits); if (isPrioritized() == 1) { priority_++; } } // End of while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) ... // // All data has been read from the read buffer. // We still need to mark the end of the encode // buffer just before sending the frame. This // allows us to accomodate multiple reads in // a single frame. // if (priority_ > 0) { #if defined(TEST) || defined(INFO) *logofs << "handleRead: WARNING! Requesting flush " << "because of " << priority_ << " prioritized " << "messages for FD#" << fd_ << ".\n" << logofs_flush; #endif if (proxy -> handleAsyncPriority() < 0) { return -1; } // // Reset the priority flag. // priority_ = 0; } // // Flush if we produced enough data. // if (proxy -> canAsyncFlush() == 1) { #if defined(TEST) || defined(INFO) *logofs << "handleRead: WARNING! Requesting flush " << "because of enough data or timeout on the " << "proxy link.\n" << logofs_flush; #endif if (proxy -> handleAsyncFlush() < 0) { return -1; } } #if defined(TEST) || defined(INFO) if (transport_ -> pending() != 0 || readBuffer_.checkMessage() != 0) { *logofs << "handleRead: PANIC! Buffer for X descriptor FD#" << fd_ << " has " << transport_ -> pending() << " bytes to read.\n" << logofs_flush; HandleCleanup(); } #endif // // Reset the read buffer. // readBuffer_.fullReset(); return 1; }
void ReadBuffer::readMessage(const unsigned char *message, unsigned int length) { // // To be here we must be the real owner // of the buffer and there must not be // pending bytes in the transport. // #ifdef TEST if (owner_ == 0) { *logofs << "ReadBuffer: PANIC! Class for FD#" << transport_ -> fd() << " doesn't " << "appear to be the owner of the buffer " << "while borrowing from the caller.\n" << logofs_flush; HandleCleanup(); } #endif // // Be sure that any outstanding data from // the transport is appended to our own // byffer. // if (transport_ -> pending() != 0) { #ifdef WARNING *logofs << "ReadBuffer: WARNING! Class for FD#" << transport_ -> fd() << " has pending " << "data in the transport while " << "borrowing from the caller.\n" << logofs_flush; #endif readMessage(); if (owner_ == 0) { convertBuffer(); } } // // Can't borrow the buffer if there is data // from a partial message. In this case add // the new data to the end of our buffer. // if (length_ == 0) { #ifdef TEST *logofs << "ReadBuffer: Borrowing " << length << " bytes from the caller for FD#" << transport_ -> fd() << " with " << length_ << " bytes in the buffer.\n" << logofs_flush; #endif delete [] buffer_; buffer_ = (unsigned char *) message; size_ = length; length_ = length; owner_ = 0; start_ = 0; } else { #ifdef TEST *logofs << "ReadBuffer: Appending " << length << " bytes from the caller for FD#" << transport_ -> fd() << " with " << length_ << " bytes in the buffer.\n" << logofs_flush; #endif appendBuffer(message, length); } }
const unsigned char *ReadBuffer::getMessage(unsigned int &controlLength, unsigned int &dataLength) { #ifdef TEST if (transport_ -> pending() > 0) { *logofs << "ReadBuffer: PANIC! The transport " << "appears to have data pending.\n" << logofs_flush; HandleCleanup(); } #endif if (length_ == 0) { #ifdef DEBUG *logofs << "ReadBuffer: No message can be located " << "for FD#" << transport_ -> fd() << ".\n" << logofs_flush; #endif if (owner_ == 0) { buffer_ = NULL; size_ = 0; transport_ -> pendingReset(); owner_ = 1; start_ = 0; } return NULL; } unsigned int trailerLength; #ifdef DEBUG *logofs << "ReadBuffer: Going to locate message with " << "start at " << start_ << " and length " << length_ << " for FD#" << transport_ -> fd() << ".\n" << logofs_flush; #endif int located = locateMessage(buffer_ + start_, buffer_ + start_ + length_, controlLength, dataLength, trailerLength); if (located == 0) { // // No more complete messages are in // the buffer. // #ifdef DEBUG *logofs << "ReadBuffer: No message was located " << "for FD#" << transport_ -> fd() << ".\n" << logofs_flush; #endif if (owner_ == 0) { // // Must move the remaining bytes in // our own buffer. // convertBuffer(); } return NULL; } else { const unsigned char *result = buffer_ + start_; if (dataLength > 0) { // // Message contains data, so go to the // first byte of payload. // result += trailerLength; start_ += (dataLength + trailerLength); length_ -= (dataLength + trailerLength); } else { // // It is a control message. // start_ += (controlLength + trailerLength); length_ -= (controlLength + trailerLength); } #ifdef DEBUG *logofs << "ReadBuffer: Located message for FD#" << transport_ -> fd() << " with control length " << controlLength << " and data length " << dataLength << ".\n" << logofs_flush; #endif remaining_ = 0; return result; } }
int ReadBuffer::readMessage() { int pendingLength = transport_ -> pending(); if (pendingLength > 0) { // // Can't move the data in the borrowed buffer, // so use the tansport buffer only if we don't // have any partial message. This can happen // with the proxy where we need to deflate the // stream. // if (length_ == 0) { unsigned char *newBuffer; length_ = transport_ -> getPending(newBuffer); if (newBuffer == NULL) { #ifdef PANIC *logofs << "ReadBuffer: PANIC! Failed to borrow " << length_ << " bytes of memory for buffer " << "in context [A].\n" << logofs_flush; #endif cerr << "Error" << ": Failed to borrow memory for " << "read buffer in context [A].\n"; HandleCleanup(); } delete [] buffer_; buffer_ = newBuffer; size_ = length_; owner_ = 0; start_ = 0; #ifdef TEST *logofs << "ReadBuffer: Borrowed " << length_ << " pending bytes for FD#" << transport_ -> fd() << ".\n" << logofs_flush; #endif return length_; } #ifdef TEST else { *logofs << "ReadBuffer: WARNING! Cannot borrow " << pendingLength << " bytes for FD#" << transport_ -> fd() << " with " << length_ << " bytes in the buffer.\n" << logofs_flush; } #endif } unsigned int readLength = suggestedLength(pendingLength); #ifdef DEBUG *logofs << "ReadBuffer: Requested " << readLength << " bytes for FD#" << transport_ -> fd() << " with readable " << transport_ -> readable() << " remaining " << remaining_ << " pending " << transport_ -> pending() << ".\n" << logofs_flush; #endif if (readLength < initialReadSize_) { readLength = initialReadSize_; } #ifdef DEBUG *logofs << "ReadBuffer: Buffer size is " << size_ << " length " << length_ << " and start " << start_ << ".\n" << logofs_flush; #endif // // We can't use the transport buffer // to read our own data in it. // #ifdef TEST if (owner_ == 0) { *logofs << "ReadBuffer: PANIC! Class for FD#" << transport_ -> fd() << " doesn't " << "appear to be the owner of the buffer " << "while reading.\n" << logofs_flush; HandleCleanup(); } #endif // // Be sure that we have enough space // to store all the requested data. // if (buffer_ == NULL || length_ + readLength > size_) { unsigned int newSize = length_ + readLength; #ifdef TEST *logofs << "ReadBuffer: Resizing buffer for FD#" << transport_ -> fd() << " in read from " << size_ << " to " << newSize << " bytes.\n" << logofs_flush; #endif unsigned char *newBuffer = allocateBuffer(newSize); memcpy(newBuffer, buffer_ + start_, length_); delete [] buffer_; buffer_ = newBuffer; size_ = newSize; transport_ -> pendingReset(); owner_ = 1; } else if (start_ != 0 && length_ != 0) { // // If any bytes are left due to a partial // message, shift them to the beginning // of the buffer. // #ifdef TEST *logofs << "ReadBuffer: Moving " << length_ << " bytes of data " << "at beginning of " << "the buffer for FD#" << transport_ -> fd() << ".\n" << logofs_flush; #endif memmove(buffer_, buffer_ + start_, length_); } start_ = 0; #ifdef DEBUG *logofs << "ReadBuffer: Buffer size is now " << size_ << " length is " << length_ << " and start is " << start_ << ".\n" << logofs_flush; #endif unsigned char *readData = buffer_ + length_; #ifdef DEBUG *logofs << "ReadBuffer: Going to read " << readLength << " bytes from FD#" << transport_ -> fd() << ".\n" << logofs_flush; #endif int bytesRead = transport_ -> read(readData, readLength); if (bytesRead > 0) { #ifdef TEST *logofs << "ReadBuffer: Read " << bytesRead << " bytes from FD#" << transport_ -> fd() << ".\n" << logofs_flush; #endif length_ += bytesRead; } else if (bytesRead < 0) { // // Check if there is more data pending than the // size of the provided buffer. After reading // the requested amount, in fact, the transport // may have decompressed the data and produced // more input. This trick allows us to always // borrow the buffer from the transport, even // when the partial read would have prevented // that. // if (transport_ -> pending() > 0) { #ifdef TEST *logofs << "ReadBuffer: WARNING! Trying to read some " << "more with " << transport_ -> pending() << " bytes pending for FD#" << transport_ -> fd() << ".\n" << logofs_flush; #endif return readMessage(); } #ifdef TEST *logofs << "ReadBuffer: Error detected reading " << "from FD#" << transport_ -> fd() << ".\n" << logofs_flush; #endif return -1; } #ifdef TEST else { *logofs << "ReadBuffer: No data read from FD#" << transport_ -> fd() << " with remaining " << remaining_ << ".\n" << logofs_flush; } #endif return bytesRead; }
NXConnection::~NXConnection() { NX_LOG_LOGDEBUG( "NXConnection's destructor called."); HandleCleanup(); }