Beispiel #1
0
void FBSession::flushRequestQueue()
{
    while ( iRequestQueue.count() ) {
      FBRequest* request = iRequestQueue.at(0);
      if (performRequest(request, false)) {
          iRequestQueue.removeAt(0);
      } else {
        startFlushTimer();
        break;
      }
    }
}
Beispiel #2
0
void Messages::actionCB()
{
  if (entry.empty()) return;

  history.push_back(entry);  // save in history

  if (entry[0] == '!') performRequest(entry);
  else {
    writeMessage("chat", g.pref.user, entry.c_str());  // display in message zone
    User::userWriting(entry.c_str());		       // send to World Management
  }
  entry = ""; // clear textfield
}
Beispiel #3
0
void Messages::performRequest(WObject* object)
{
  if (object && nclicks > 0) {
    clicked[0]=object->pos.x;
    clicked[1]=object->pos.y;
    clicked[2]=object->pos.z;
    clicked[3]=object->pos.az;
    clicked[4]=object->pos.bbsize.v[0];
    clicked[5]=object->pos.bbsize.v[1];
    clicked[6]=object->pos.bbsize.v[2];
    nclicks--;
    if (!entry.empty()) performRequest(entry);
  }
}
void CrossfireServer::received(wchar_t* msg) {
	if (!m_handshakeReceived) {
		if (wcsncmp(msg, HANDSHAKE, wcslen(HANDSHAKE)) == 0) {
			processHandshake(msg);
			m_lastRequestSeq = -1;
		} else {
			Logger::error("Crossfire content received before handshake, not processing it");
		}
		return;
	}

	m_inProgressPacket->append(std::wstring(msg));
	std::wstring packet;
	do {
		wchar_t* parseErrorMessage = NULL;
		bool errorMessageRequiresFree = false;
		int code = CODE_OK;
		packet.clear();

		if (m_inProgressPacket->find(HEADER_CONTENTLENGTH) != 0) {
			code = CODE_MALFORMED_PACKET;
			parseErrorMessage = L"request packet does not start with 'Content-Length:', not processing it";
			m_inProgressPacket->clear();
			break;
		}

		size_t endIndex = m_inProgressPacket->find(wchar_t('\r'));
		if (endIndex == std::wstring::npos) {
			code = CODE_MALFORMED_PACKET;
			parseErrorMessage = L"request packet does not contain '\r', not processing it";
			m_inProgressPacket->clear();
			break;
		}

		size_t headerLength = wcslen(HEADER_CONTENTLENGTH);
		std::wstring lengthString = m_inProgressPacket->substr(headerLength, endIndex - headerLength);
		int lengthValue = _wtoi(lengthString.c_str());
		if (!lengthValue) {
			code = CODE_MALFORMED_PACKET;
			parseErrorMessage = L"request packet does not have a valid 'Content-Length' value, not processing it";
			m_inProgressPacket->clear();
			break;
		}

		if (m_inProgressPacket->find(L"\r\n", endIndex) != endIndex) {
			code = CODE_MALFORMED_PACKET;
			parseErrorMessage = L"request packet does not follow initial '\\r' with '\\n', not processing it";
			m_inProgressPacket->clear();
			break;
		}

		// TODO for now just skip over "tool:" lines, though these should really be validated

		size_t toolEnd = m_inProgressPacket->find(L"\r\n\r\n", endIndex);
		if (toolEnd == std::wstring::npos) {
			code = CODE_MALFORMED_PACKET;
			parseErrorMessage = L"request packet does not contain '\\r\\n\\r\\n' to delimit its header, not processing it";
			m_inProgressPacket->clear();
			break;
		}
		size_t toolsLength = toolEnd - endIndex;
		size_t targetLength = wcslen(HEADER_CONTENTLENGTH) + lengthString.length() + 3 * LINEBREAK_LENGTH + toolsLength + lengthValue;

		if (targetLength <= m_inProgressPacket->length()) {
			packet.assign(m_inProgressPacket->substr(0, targetLength));
			m_inProgressPacket->erase(0, targetLength);
		}

		if (packet.length()) {
			CrossfireRequest* request = NULL;
			code = m_processor->parseRequestPacket(&packet, &request, &parseErrorMessage);
			if (code != CODE_OK) {
				errorMessageRequiresFree = true;
			} else {
				unsigned int seq = request->getSeq();
				if (!(m_lastRequestSeq == -1 || seq == m_lastRequestSeq + 1)) {
					// TODO handle out-of-order packets
					Logger::log("packet received out of sequence, still processing it");
				}
				m_lastRequestSeq = seq;
				m_processingRequest = true;
				if (!performRequest(request)) {
					/*
					 * the request's command was not handled by the server,
					 * so try to delegate to the specified context, if any
					 */
					CrossfireContext* context = getRequestContext(request);
					if (!context) {
						Logger::error("request command was unknown to the server and a valid context id was not provided, not processing it");
					} else {
						if (!context->performRequest(request)) {
							Logger::error("request command was unknown to the server and to the specified context, not processing it");
						}
					}
				}
				m_processingRequest = false;
				delete request;

				/*
				 * Debugger events may have been received in response to the request that was
				 * just processed.  These events can be sent now that processing of the request
				 * is complete.
				 */
				sendPendingEvents();
			}
		}

		if (code) {
			CrossfireResponse response;
			response.setCode(CODE_MALFORMED_PACKET);
			response.setMessage(parseErrorMessage);
			if (errorMessageRequiresFree) {
				free(parseErrorMessage);
			}
			Value emptyBody;
			emptyBody.setType(TYPE_OBJECT);
			response.setBody(&emptyBody);
			sendResponse(&response);
		}
	} while (packet.length() > 0 && m_inProgressPacket->length() > 0);
}
Beispiel #5
0
void FBSession::send (FBRequest* aRequest) {
    performRequest (aRequest, true);
}
//=============================================================================
// METHOD: SPELLipcClientInterface::sendRequest
//=============================================================================
SPELLipcMessage* SPELLipcClientInterface::sendRequest( SPELLipcMessage* msg, unsigned long timeoutSec )
{
    DEBUG("[IPC-CLI-" + m_name + "] Send request to server");
    msg->setKey(m_clientKey);
    return performRequest( *m_writer, msg, timeoutSec );
}
Beispiel #7
0
Datei: slave.c Projekt: rv1/esb
int beginSlavery(int fd)
{
    uint16_t randContext[3];
    for(int i = 0; i < 3; i++)
    {
        randContext[i] = time(NULL) ^ getpid();
    }
    
    int returnCode = -1;
    
    json_t* params = NULL;
    json_t* nextCommand = NULL;
    
    char** values = NULL;
    
    struct workerTask* tasks = NULL;
    
    uint32_t connPoolSize = 128;
    uint32_t connPoolCount = 0;
    void** connPool = __xmalloc(sizeof(void*) * connPoolSize);
    memset(connPool, 0, sizeof(void*) * connPoolSize);
    
    //recieve initial parameters
    params = readCommand(fd, 5000);
    if(!params)
    {
        fprintf(stderr, "No initialization packet\n");
        goto exit;
    }
    
    //make sure the initial packet has all of the required info
    uint64_t slaveID;
    const char* command;
    const char* address;
    const char* username;
    const char* password;
    const char* tableName;
    int port;
    int errorChecking;
    int valueLength;
    int result = json_unpack(params, "{s:s, s:s, s:i, s:I, s:s, s:s, s:s, s:b, s:i}",
                             "command",         &command,
                             "address",         &address,
                             "port",            &port,
                             "slave-id",        &slaveID,
                             "username",        &username,
                             "password",        &password,
                             "table",           &tableName,
                             "error-checking",  &errorChecking,
                             "value-length",    &valueLength);
    if(result != 0 || strcmp(command, "init") || port <= 0 || port > 65535)
    {
        fprintf(stderr, "Invalid initialization packet recieved\n");
        goto exit;
    }

    uint64_t numKeys = 0;
    
    //loop and execute commands from the master
    while(1)
    {
        nextCommand = readCommand(fd, 15000);
        if(!nextCommand)
        {
            fprintf(stderr, "Invalid next command\n");
            goto exit;
        }
                        
        const char* command;
        int result = json_unpack(nextCommand, "{s:s}", "command", &command);
        if(result == -1)
        {
            fprintf(stderr, "Packet missing command field\n");
            goto exit;
        }
        
        //parse commands and modify keyRange array if needed
        struct workerTask task;
        
        if(!strcmp(command, "add"))
        {
            uint64_t numKeysToAdd;
            int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToAdd);
            if(result == -1)
            {
                goto exit;
            }

            if(errorChecking)
            {
                values = __xrealloc(values, sizeof(char*) * (numKeys + numKeysToAdd));
                for(uint64_t i = 0; i < numKeysToAdd; i++)
                {
                    values[numKeys + i] = __xmalloc(valueLength + 1);
                    for(int j = 0; j < valueLength; j++)
                    {
                        values[numKeys + i][j] = (erand48(randContext) * 26) + 'A';
                    }
                    values[numKeys + i][valueLength] = '\0';
                }
            }
            task.startingKey = slaveID + numKeys;
            task.numKeys = numKeysToAdd;
            task.type = kClientAddKeys;
            task.values = values;
            numKeys += task.numKeys;
        }
        else if(!strcmp(command, "remove"))
        {
            uint64_t numKeysToRemove;
            
            int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToRemove);
            if(result == -1)
            {
                goto exit;
            }
            
            if(errorChecking)
            {
                uint64_t position = numKeys - numKeysToRemove;
                for(uint64_t i = 0; i < numKeysToRemove; i++)
                {
                    free(values[position + i]);
                }
                values = __xrealloc(&values, sizeof(char*) * (numKeys - numKeysToRemove));
            }
            if(numKeysToRemove > numKeys)
            {
                goto exit;
            }
            task.startingKey = slaveID + numKeys - numKeysToRemove;
            task.numKeys = numKeysToRemove;
            task.type = kClientRemoveKeys;
            task.values = NULL;
            numKeys -= numKeysToRemove;
        }
        else if(!strcmp(command, "test"))
        {
            json_t* array = json_object_get(nextCommand, "workload");

            //right now we only need 1 workload type
            if(!(json_is_array(array) && json_array_size(array) == kWorkloadTypes))
            {
                goto exit;
            }
            for(int i = 0; i < kWorkloadTypes; i++)
            {
                task.workloadComposition[i] = json_number_value(json_array_get(array, i));
            }
            int result = json_unpack(nextCommand, "{s:I}", "amount", &task.count);
            if(result == -1)
            {
                goto exit;
            }
            task.startingKey = slaveID;
            task.numKeys = numKeys;
            task.values = values;
            task.type = kClientRunWorkload;
        }
        else if(!strcmp(command, "quit"))
        {
            returnCode = 0;
            goto exit;
        }
        else
        {
            fprintf(stderr, "unknown command from client: %s\n", command);
            goto exit;
        }
        
        int numClients;
        result = json_unpack(nextCommand, "{s:i, s:F}", "num-clients", &numClients, "throughput", &task.throughput);
        if(result == -1)
        {
            fprintf(stderr, "Packet missing number of clients or throughput value\n");
            goto exit;
        }
                
        task.connOpenDelay = 0;
        
        //fill out the generic task information
        task.table = tableName;
        task.valueSize = valueLength;
        task.workerID = slaveID;
        task.hostname = address;
        task.username = username;
        task.password = password;
        task.port = port;
        
        //split the request between the clients
        while(numClients >= connPoolSize)
        {
            size_t oldSize = connPoolSize;
            connPoolSize *= 8;
            connPool = __xrealloc(connPool, connPoolSize * sizeof(void*));
            memset(&connPool[oldSize], 0, sizeof(void*) * oldSize * 7);
        }
        
        if(numClients < connPoolCount)
        {
            for(int i = connPoolCount - 1; i >= numClients; i--)
            {
                storage_disconnect(connPool[i]);
                connPool[i] = NULL;
            }
        }
        
        tasks = __xmalloc(sizeof(struct workerTask) * numClients);
        splitTasks(&task, tasks, numClients, connPool);
                
        //perform the request
        json_t* requestResponse;
        performRequest(tasks, numClients, &requestResponse);
        
        //save the connections for next time
        for(int i = 0; i < numClients; i++)
        {
            connPool[i] = tasks[i].conn;
        }
        connPoolCount = numClients;
        
        //send the result back to the master
        char* serialResponse = json_dumps(requestResponse, JSON_COMPACT);
        json_decref(requestResponse);
        size_t len = strlen(serialResponse);
        if(len > 1048576)
        {
            fprintf(stderr, "Response too large (%zd)\n", len);
            free(serialResponse);
            goto exit;
        }
        char sizeBuf[9];
        sprintf(sizeBuf, "%08d", (int)len);
        sendAll(fd, sizeBuf, 8);
        
        if(sendAll(fd, serialResponse, strlen(serialResponse)) == -1)
        {
            free(serialResponse);
            goto exit;
        }
        free(serialResponse);

        free(tasks);
        tasks = NULL;        
        
        //free the parsed command
        json_decref(nextCommand);
        nextCommand = NULL;
    }
    
exit:
    for(uint32_t i = 0; i < connPoolCount; i++)
    {
        storage_disconnect(connPool[i]);
    }
    free(connPool);
    free(tasks);
    json_decref(nextCommand);
    json_decref(params);
    if(values)
    {
        for(uint64_t i = 0; i < numKeys; i++)
        {
            free(values[i]);
        }
        free(values);
    }
    return returnCode;
}