/** * Close and unlock a file which was previously opened and locked using sfs_fopen. * * Parameters: fp - file pointer to the file which you wish to close * Returns: 1 on success, 0 otherwise */ int sfs_fclose(FILE *fp) { if(fp == NULL) return 0; mutex_lock(memory); // Find this process and file resource node *resource = find_file_node_fp(memory, fp); node *process = find_process_node(memory, getpid()); if(resource == NULL || process == NULL) { mutex_unlock(memory); return 0; } resource->fp = NULL; // Convert back to claim edge delete_out_edge(memory, resource, process); add_out_edge(memory, process, resource); // Close file int result = fclose(fp); // Broadcast conditional variable pthread_cond_broadcast(get_cycle_cond(memory)); mutex_unlock(memory); return (result != EOF); }
/** * Open and lock the given file, ensuring that no deadlock will occur now or in the future over contention for this file. * If opening this file immediately would cause a deadlock, this method will block until the file can be safely opened and locked. * If the file cannot be opened, NULL is returned. * * Parameters: path - path to the file you wish to open and lock * mode - mode in which to open the file (same as the argument to fopen()) * Returns: A file pointer to the opened file or NULL on error */ FILE *sfs_fopen(char *path, char *mode) { mutex_lock(memory); // Turn claim edge to assignment edge node *resource = find_file_node(memory, path); node *process = find_process_node(memory, getpid()); if(resource == NULL || process == NULL) {\ mutex_unlock(memory); return NULL; } delete_out_edge(memory, process, resource); add_out_edge(memory, resource, process); // While a cycle exists while(cycle_exists(memory)) { // Convert back to claim edge delete_out_edge(memory, resource, process); add_out_edge(memory, process, resource); // Wait pthread_cond_wait(get_cycle_cond(memory), get_lock(memory)); // Add edge back delete_out_edge(memory, process, resource); add_out_edge(memory, resource, process); } // Upon getting the lock and assuring no cycle, open the file FILE *res = fopen(path, mode); resource->fp = res; mutex_unlock(memory); return res; }
static ATCODEC_RET process_received_data(ATcodec_Tree_t *tree, int nb, char *global_buffer, int *global_len) { ATCODEC_RET res = ATCODEC_TRUE; int len_dec; char memory[INTERNAL_BUFFER_SIZE]; ATcodec_Memory_t mem; while (nb--) /* nb is the number of \r in the buffer, ie. the number of potential AT commands */ { ATcodec_Memory_Init(&mem, &memory[0], sizeof(memory), 1, NULL, NULL); if (find_process_node(tree, global_buffer, &mem, &len_dec) != ATCODEC_TRUE) { /* Go to the next potential command */ for(len_dec = 0 ; len_dec < *global_len && global_buffer[len_dec] != '\r' ; len_dec++) { // nothing } ATCODEC_PRINT("PURGE\n"); if(global_buffer[len_dec++] == '\r') { if(global_buffer[len_dec++] == '\0') len_dec++; } } if (--len_dec >= *global_len) len_dec = *global_len; if (*global_len == len_dec) { ATCODEC_ZERO_MEMSET(global_buffer, 0, *global_len*sizeof(char)); *global_len = 0; } else { memmove(/*dest*/global_buffer, /*src*/global_buffer+len_dec, /*nb bytes*/*global_len-len_dec); ATCODEC_ZERO_MEMSET(global_buffer+*global_len-len_dec, 0, (len_dec)*sizeof(char)); *global_len -= len_dec; } } return res; }