Example #1
0
File: rpc.c Project: dyustc/searaft
int add_method_entry(struct method_lookup *lookup, const char *method,
    rpc_method_impl_t target_method_impl, void *data) {
    int i;
    for(i = 0; i < METHOD_LOOKUP_CACHE_SIZE; i++) {
        if(!lookup->cached_method_name[i]) {
            lookup->cached_method_name[i] = private_strdup(method);
            lookup->cached_target_method_impl[i] = target_method_impl;
            lookup->cached_satellite_data[i] = data;
            break;
        }
    }
    if(i == METHOD_LOOKUP_CACHE_SIZE) {
        struct method_entry *entry = (struct method_entry *)malloc(
            sizeof(struct method_entry));
        if(!entry) {
            return 1;
        }
        entry->method_name = private_strdup(method);
        entry->target_method_impl = target_method_impl;
        entry->satellite_data = data;
        entry->next = NULL;

        if(lookup->head == NULL) {
            lookup->head = entry;
        } else {
            struct method_entry *iter = lookup->head;
            while(iter->next != NULL) {
                iter = iter->next;
            }
            iter->next = entry;
        }
    }

    return 0;
}
Example #2
0
/**
 * \brief Gets the file name without the path component.
 * \param path Path string.
 * \return New string or NULL.
 */
char* lisys_path_basename (
	const char* path)
{
	char* ptr;

	ptr = strrchr (path, '/');
	if (ptr == NULL)
		return private_strdup (path);

	return private_strdup (ptr + 1);
}
Example #3
0
struct method_t *make_request_vote_rpc_method(struct request_vote_input_t *input) {
    struct data_t **params = (struct data_t **)malloc(
        sizeof(struct data_t *)*REQUEST_VOTE_PARAM_COUNT);
    if(!params) {
        DBG_LOG(LOG_FATAL, "memory allocation failed");
        return NULL;
    }

    params[0] = uint64_to_data_t(input->term);
    params[1] = uint32_to_data_t(input->candidate_id);
    params[2] = uint64_to_data_t(input->last_log_index);
    params[3] = uint64_to_data_t(input->last_log_term);

    char *method_name = private_strdup(REQUEST_VOTE_RPC);

    struct method_t *request_vote = 
        (struct method_t *)malloc(sizeof(struct method_t));
    if(!request_vote) {
        DBG_LOG(LOG_FATAL, "memory allocation failed");
        if(method_name) free(method_name);
        for(int i = 0; i < REQUEST_VOTE_PARAM_COUNT; i++) {
            if(params[i]) {
                free_data_t(params[i]);
            }
        }
        free(params);
        return NULL;
    }

    request_vote->name = method_name;
    request_vote->params = params;
    request_vote->nparams = REQUEST_VOTE_PARAM_COUNT;

    return request_vote;
}
Example #4
0
File: rpc.c Project: dyustc/searaft
struct data_t *deserialize_data(json_t *json_data) {
    struct data_t *data = (struct data_t *)malloc(sizeof(struct data_t));
    if(json_is_integer(json_data)) {
        data->type = RPC_INT;
        data->value = (json_int_t *)malloc(sizeof(json_int_t));
        *(json_int_t *)data->value = json_integer_value(json_data);
    } else if(json_is_real(json_data)) {
        data->type = RPC_REAL;
        data->value = (double *)malloc(sizeof(double));
        *(double *)data->value = json_real_value(json_data);
    } else if(json_is_string(json_data)) {
        data->type = RPC_STRING;
        data->value = private_strdup(json_string_value(json_data));
    } else if(json_is_array(json_data)) {
        data->type = RPC_VECTOR;
        data->length = json_array_size(json_data);
        data->child = (struct data_t **)malloc(sizeof(struct data_t *)*data->length);
        for(int i = 0; i < data->length; i++) {
            data->child[i] = deserialize_data(json_array_get(json_data, i));
        }
    } else {
        return NULL;
    }
    return data;
}
Example #5
0
File: rpc.c Project: dyustc/searaft
//deserializes the method which serialized at caller
//returns method name to be called and the params/nparams
//are the arguments to the method call
//returns NULL on error
struct method_t *deserialize_method_call(const char *serialized) {
    json_t *root;
    json_error_t parse_error;
    
    root = json_loads(serialized, 0, &parse_error);

    if(!root || !json_is_object(root)) {
        if(root) json_decref(root);
        return NULL;
    }

    json_t *json_method_name = json_object_get(root, METHOD_JSON_KEY);
    json_t *json_method_params = json_object_get(root, PARAMS_JSON_KEY);

    if(!json_method_name || !json_method_params) {
        json_decref(root);
        return NULL;
    }
    
    char *method_name = NULL;
    if(!json_is_string(json_method_name)) {
        json_decref(root);
        return NULL;
    }
    method_name = private_strdup(json_string_value(json_method_name));

    struct data_t *envelope = deserialize_data(json_method_params);
    if(!envelope || envelope->type != RPC_VECTOR) {
        free(method_name);
        json_decref(root);
        return NULL;
    }

    struct method_t *mtd = (struct method_t *)
        malloc(sizeof(struct method_t));
    if(!mtd) {
        free(method_name);
        free_data_t(envelope);
        json_decref(root);
        return NULL;
    }

    mtd->name = method_name;
    mtd->params = envelope->child;
    mtd->nparams = envelope->length;

    free(envelope);
    json_decref(root);

    return mtd;
}
Example #6
0
File: rpc.c Project: dyustc/searaft
// method result is expected in following format
// {
//        "result-type" : "<SUCCESS/ERROR>",
//        "result" : <error string or actual result>
// }
// return value or error needs to be freed
struct data_t *deserialize_result(const char *serialized, char **error) {
    json_t *root;
    json_error_t parse_error;
    
    root = json_loads(serialized, 0, &parse_error);

    if(!root || !json_is_object(root)) {
        if(root) json_decref(root);
        return NULL;
    }

    json_t *result_type = json_object_get(root, RESULT_TYPE_JSON_KEY);
    json_t *result = json_object_get(root, RESULT_JSON_KEY);

    if(!result_type || !result) {
        json_decref(root);
        return NULL;
    }

    if(!json_is_string(result_type)) {
        json_decref(root);
        return NULL;
    }

    if(0 == strcmp("SUCCESS", json_string_value(result_type))) {
        struct data_t *data = deserialize_data(result);
        json_decref(root);
        return data;
    } else {
        if(!json_is_string(result)) {
            json_decref(root);
            return NULL;
        }
        *error = private_strdup(json_string_value(result));
        json_decref(root);
    }

    return NULL;
}
Example #7
0
struct method_t *make_append_entries_rpc_method(struct append_entries_input_t *input) {
    struct data_t **params = (struct data_t **)malloc(sizeof(struct data_t *)*APPEND_ENTRIES_PARAM_COUNT);
    if(!params) {
        DBG_LOG(LOG_FATAL, "memory allocation failed");
        return NULL;
    }

    params[0] = uint64_to_data_t(input->term);
    params[1] = uint32_to_data_t(input->leader_id);
    params[2] = uint64_to_data_t(input->prev_log_index);
    params[3] = uint64_to_data_t(input->prev_log_term);
    params[4] = uint64_to_data_t(input->leader_commit_index);

    struct data_t *entries_array = (struct data_t *)malloc(sizeof(struct data_t));
    if(entries_array) {
        entries_array->type = RPC_VECTOR;
        entries_array->length = input->nentries;
        entries_array->child = (struct data_t **)malloc(
                sizeof(struct data_t *)*input->nentries);
        if(entries_array->child) {
            int alldone = 1;
            for(int i = 0; i < input->nentries; i++) {
                entries_array->child[i] = log_to_data_t(input->entries[i]);
                if(!entries_array->child[i]) {
                    entries_array->length = i;
                    alldone = 0; break;
                }
            }
            if(alldone) {
                params[5] = entries_array;
            } else {
                free_data_t(entries_array);
            }
        } else {
            free(entries_array);
        }
    }
    
    char *method_name = private_strdup(APPEND_ENTRIES_RPC);

    //none of the above allocation failure are handled assuming if 
    //one fails the subsequent allocation will also fail including 
    //allocation of append_entries hence all of them handled together 
    // below
    struct method_t *append_entries = (struct method_t *)malloc(
        sizeof(struct method_t));    
    if(!append_entries) {
        DBG_LOG(LOG_FATAL, "memory allocation failed");
        if(method_name) free(method_name);
        for(int i = 0; i < APPEND_ENTRIES_PARAM_COUNT; i++) {
            if(params[i]) {
                free_data_t(params[i]);
            }
        }
        free(params);
        return NULL;
    }

    append_entries->name = method_name;
    append_entries->params = params;
    append_entries->nparams = APPEND_ENTRIES_PARAM_COUNT;

    return append_entries;
}