PageResponse* server_handle_page_request(int client, PageRequest *request) { if (request->nodeId < 0 || request->nodeId >= totalNumberOfClients) { logger_log_message("Invalid client ID was supplied to server.", ERROR); PageResponse* response = (PageResponse*) malloc(sizeof(PageResponse)); response->errorCode = -2; return response; } if (request->pageNumber < 0 || request->pageNumber >= currentPage + 1) { logger_log_message("Invalid page number was requested.", ERROR); PageResponse* response = (PageResponse*) malloc(sizeof(PageResponse)); response->errorCode = -4; return response; } ServerPageEntry* pageEntry = pages[request->pageNumber]; ClientEntry* owner = pageEntry->owner; PageResponse* response = server_forward_page_request(client, request, owner); if (response->errorCode != 0) { logger_log_message("Page forward request failed.", ERROR); return response; } return response; }
NodeExitResponse *server_handle_node_exit(NodeExitRequest *request) { NodeExitResponse* response = (NodeExitResponse*) malloc(sizeof(NodeExitResponse)); if (request->nodeId < 0 || request->nodeId >= totalNumberOfClients) { logger_log_message("Invalid client ID was supplied to server.", ERROR); response->errorCode = -2; return response; } clients[request->nodeId]->isActive = false; response->errorCode = 0; logger_log_message("node_exit request handled successfully.", INFO); return response; }
NodeInitResponse *server_handle_node_init(NodeInitRequest *request, int clientSocketId) { NodeInitResponse* response = (NodeInitResponse*) malloc(sizeof(NodeInitResponse)); if (currentClient == totalNumberOfClients - 1) { logger_log_message("More clients than originally allowed tried to register.", ERROR); response->errorCode = -1; return response; } ClientEntry* newClient = client_entry_new(++currentClient, clientSocketId, request->forwardAddress, request->forwardPort); clients[currentClient] = newClient; response->errorCode = 0; response->assignedNodeId = currentClient; response->numberOfNodes = totalNumberOfClients; response->numberOfPages = totalNumberOfPages; logger_log_message("node_init request handled successfully.", INFO); return response; }
InvalidationResponse* invalidate_page(int nodeId, long pageNumber, ClientEntry* client) { InvalidationRequest *invalidationRequest = (InvalidationRequest *) malloc(sizeof(InvalidationRequest)); invalidationRequest->nodeId = nodeId; invalidationRequest->pageNumber = pageNumber; InvalidationResponse *response = server_forward_invalidation(invalidationRequest, client); if (response->errorCode != 0) logger_log_message("Error invalidating page.", ERROR); free(invalidationRequest); return response; }
AllocResponse *server_handle_alloc(AllocRequest *request) { AllocResponse* response = (AllocResponse*) malloc(sizeof(AllocResponse)); if (request->nodeId < 0 || request->nodeId >= totalNumberOfClients) { logger_log_message("Invalid client ID was supplied to server.", ERROR); response->errorCode = -2; return response; } if (mallocsPerClient[request->nodeId] + 1 <= lastMalloc) { mallocsPerClient[request->nodeId]++; response->errorCode = 0; response->address = mallocAddresses[mallocsPerClient[request->nodeId]]; response->servedFromCache = true; return response; } int pageSize = getpagesize(); int numberOfRequestedPages = (int) ceil(request->size * 1.0 / pageSize); if (totalNumberOfPages - (currentPage + 1) < numberOfRequestedPages) { logger_log_message("Not enough memory available for perform allocation.", ERROR); response->errorCode = -3; return response; } int i; ClientEntry* requestingClient = clients[request->nodeId]; long startingAddress = (currentPage + 1) * pageSize; for (i = 0; i < numberOfRequestedPages; i++) { currentPage++; pages[currentPage] = server_page_entry_new(currentPage, requestingClient); } response->errorCode = 0; response->address = startingAddress; response->servedFromCache = false; mallocsPerClient[request->nodeId]++; lastMalloc++; mallocAddresses[lastMalloc] = startingAddress; return response; }
void server_teardown() { logger_log_message("Shutting down server...", INFO); int i; for (i = 0; i < currentPage; i++) server_page_entry_free(pages[i]); free(pages); for (i = 0; i < totalNumberOfClients; i++) { printf("Closing socket: %d\n", clients[i]->clientSocketId); shutdown(clients[i]->clientSocketId, SHUT_RDWR); close(clients[i]->clientSocketId); client_entry_free(clients[i]); } free(clients); free(mallocsPerClient); free(mallocAddresses); currentPage = -1; currentClient = -1; logger_log_message("Shutting down server finished.", INFO); logger_log_message("Server teardown completed", INFO); logger_close(); }
void server_startup(long numberOfPages, int numberOfClients) { logger_log_message("Starting up server...", INFO); currentPage = -1; currentClient = -1; mallocsPerClient = (int*) malloc(sizeof(int) * numberOfClients); mallocAddresses = (long*) malloc(sizeof(long) * numberOfPages); lastMalloc = -1; int i; for (i = 0; i < numberOfClients; i++) mallocsPerClient[i] = -1; for (i = 0; i < 1024; i++){ barriers[i] = numberOfClients; } pages = (ServerPageEntry**) malloc(sizeof(ServerPageEntry*) * numberOfPages); clients = (ClientEntry**) malloc(sizeof(ClientEntry*) * numberOfClients); totalNumberOfPages = numberOfPages; totalNumberOfClients = numberOfClients; logger_log_message("Starting up server finished.", INFO); }
void server_handle_barrier(BarrierRequest *request) { int barrierId = request->barrierId; barriers[barrierId]--; logger_log_message("Barrier was requested", INFO); if(barriers[barrierId] == 0){ int nodeIndex = 0; logger_log_message("Barrier was completed, answering to nodes", INFO); for(; nodeIndex < totalNumberOfClients; nodeIndex++){ char message [MAXDATASIZE]; sprintf( message, RES_FORMAT, ZERO, ZERO, ZERO, (long) ZERO, VOID ); send(clients[nodeIndex]->clientSocketId, message, strlen(message), 0); } } }
PageResponse* server_forward_page_request(int client, PageRequest *request, ClientEntry* owner) { int clientWithPageSocket = server_connect(owner->forwardIpAddress, owner->forwardPort); char logMessage[100]; sprintf(logMessage, "Forwarding request to %s:%d", owner->forwardIpAddress, owner->forwardPort); logger_log_message(logMessage, INFO); char message[MAXDATASIZE]; int buffer1 = 0; int buffer2 = 0; long buffer3 = 0; sprintf( message, REQ_FORMAT, GET, PAGE, request->nodeId, request->ownershipOnly, request->readOnlyMode, request->pageNumber ); send(clientWithPageSocket, message, strlen(message), 0); recv(clientWithPageSocket, message, MAXDATASIZE, 0); PageResponse* response = (PageResponse*) malloc(sizeof(PageResponse)); sscanf( message, RES_FORMAT, &response->errorCode, &buffer1, &buffer2, &buffer3, response->pageContents ); // requesting not only ownership and no error if (!request->ownershipOnly && response->errorCode == 0) { char *contentBeforePage = strchr(message, '&'); memcpy(response->pageContents, contentBeforePage + 1, getpagesize()); } printf("Closing socket: %d\n", clientWithPageSocket); shutdown(clientWithPageSocket, SHUT_RDWR); close(clientWithPageSocket); return response; }
InvalidationResponse* server_handle_invalidation(InvalidationRequest *request) { if (request->nodeId < 0 || request->nodeId >= totalNumberOfClients) { logger_log_message("Invalid client ID was supplied to server.", ERROR); InvalidationResponse* response = (InvalidationResponse*) malloc(sizeof(InvalidationResponse)); response->errorCode = -2; return response; } if (request->pageNumber < 0 || request->pageNumber >= currentPage + 1) { logger_log_message("Invalid page number was requested.", ERROR); InvalidationResponse* response = (InvalidationResponse*) malloc(sizeof(InvalidationResponse)); response->errorCode = -4; return response; } ServerPageEntry* pageEntry = pages[request->pageNumber]; g_slist_foreach(pageEntry->clientsWithCopies, invalidate_page_wrapper, request); g_slist_free(pageEntry->clientsWithCopies); pageEntry->clientsWithCopies = NULL; InvalidationResponse* response = (InvalidationResponse*) malloc(sizeof(InvalidationResponse)); response->errorCode = 0; // TODO We might need to add an extra check. return response; }
/****************************************************************************** ** Function : save_a800_pal ** ** Objective : This function saves the palette as an Atari800 style file ** ** Parameters : file - name of file to save Atari 800 palette to ** pal - palette to save ** ** return : Error code ** ******************************************************************************/ int save_a800_pal ( char *file, int *pal ) { int i,j; FILE *fp; /* * Open the atari800 palette and get values */ if ((fp = fopen(file,"wb")) == NULL) { sprintf ( msg, "Cound not open Atari800 Pallete file: %s", file ); logger_log_message ( LOG_ERROR, msg, "" ); return -1; } for (i = 0; i < 256; ++i ) { for (j = 16; j >= 0; j -= 8) { fputc(pal[i]>>j, fp); } } fclose(fp); return 0; } /* end save_a800_pal */
InvalidationResponse* server_forward_invalidation(InvalidationRequest *request, ClientEntry* client) { int cx = server_connect(client->forwardIpAddress, client->forwardPort); char logMessage[100]; sprintf(logMessage, "Invalidating page to %s:%d\n", client->forwardIpAddress, client->forwardPort); logger_log_message(logMessage, INFO); char message[MAXDATASIZE]; int buffer1 = 0; int buffer2 = 0; long buffer3 = 0; char buffer4[2]; sprintf(message, REQ_FORMAT, GET, INVA, request->nodeId, ZERO, ZERO, request->pageNumber); send(cx, message, strlen(message), 0); recv(cx, message, MAXDATASIZE, 0); InvalidationResponse* response = (InvalidationResponse*) malloc(sizeof(InvalidationResponse)); sscanf( message, RES_FORMAT, &response->errorCode, &buffer1, &buffer2, &buffer3, buffer4 ); printf("Closing socket: %d\n", cx); shutdown(cx, SHUT_RDWR); close(cx); return response; }
/****************************************************************************** ** Function : convert_palette ** ** Objective : This function converts the file format from atari800 to db ** ** Parameters : old_file - name of file containing atari800 binary array ** new_name - name of palette to store ** ** return : Error code ** ******************************************************************************/ int convert_palette ( char *old_file, char *new_name ) { int pal[256]; int i,j,c; FILE *fp; /* * Open the atari800 palette and get values */ if ((fp = fopen(old_file,"rb")) == NULL) { sprintf ( msg, "Cound not open Atari800 Pallete file: %s", old_file ); logger_log_message ( LOG_ERROR, msg, "" ); return -1; } for (i = 0; i < 256; ++i ) { pal[i] = 0; for (j = 16; j >= 0; j -= 8) { c = fgetc(fp); if (c == EOF) { fclose(fp); return -1; } pal[i] |= c << j; } } fclose(fp); /* * Now save to the new file as kat5200 palette */ if ( save_palette ( new_name, pal ) ) return -1; return 0; } /* end convert_palette */