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;
}
Exemple #11
0
/******************************************************************************
**  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;
}
Exemple #13
0
/******************************************************************************
**  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 */