Пример #1
0
TASKQ *task_freeq (TASKQ *q)
{
  TASK *t;

  task_stop (q);
  wait_mutex (q);
  debug ("freeing queue\n");
  while ((t = q->queue) != NULL)
  {
    q->queue = t->next;
    free (t);
  }
  debug ("freeing pool\n");
  while ((t = q->pool) != NULL)
  {
    q->pool = t->next;
    free (t);
  }
  debug ("closing event and critical section\n");
  end_mutex (q);
  destroy_mutex (q);
  destroy_ready (q);
  free (q);
  return (NULL);
}
Пример #2
0
void signal(int threadid, int *msg, int senderid, int signal_type)
{
	int i = 0;

	wait_mutex(&working_threads[threadid].waiting_for_signal_mutex);
	if(working_threads[threadid].signal_senderid != senderid || working_threads[threadid].waiting_for_signal == 0 || working_threads[threadid].expected_signal_type != signal_type)
	{
		// unexpected signal, discard it
		leave_mutex(&working_threads[threadid].waiting_for_signal_mutex);
		return;
	}

	// send signal
	working_threads[threadid].expected_signal_type = OFS_THREADSIGNAL_NOSIGNAL;
	working_threads[threadid].signal_type = signal_type;
	working_threads[threadid].signal_senderid = senderid;

	if(msg != NULL)
	{
		working_threads[threadid].signal_msg[0] = *msg++;
		working_threads[threadid].signal_msg[1] = *(msg++);
		working_threads[threadid].signal_msg[2] = *(msg++);
		working_threads[threadid].signal_msg[3] = *(msg);
	}
	
	leave_mutex(&working_threads[threadid].waiting_for_signal_mutex);

	working_threads[threadid].waiting_for_signal = 0;
}
Пример #3
0
// this function should be invoked before sending msgs
void set_wait_for_signal(int threadid, int signal_type, int senderid)
{
	wait_mutex(&working_threads[threadid].waiting_for_signal_mutex);
	working_threads[threadid].expected_signal_type = signal_type;
	working_threads[threadid].signal_senderid = senderid;
	working_threads[threadid].waiting_for_signal = 1;
	leave_mutex(&working_threads[threadid].waiting_for_signal_mutex);
}
Пример #4
0
int check_idle()
{
	int ret;
	wait_mutex(&idle_threads_mutex);
	ret = idle_threads > 0;	
	leave_mutex(&idle_threads_mutex);
	return ret;
}
Пример #5
0
void free(void *ptr)
{
#	ifdef SAFE
	wait_mutex(&malloc_mutex);
#	endif
	_mem_free(ptr);
#	ifdef SAFE
	leave_mutex(&malloc_mutex);
#	endif
}
Пример #6
0
/*
 * Stop and wait for all threads to exit (assume we are one of them).
 * If stop is already set, return non-zero.
 */
int task_stop (TASKQ *q)
{
  wait_mutex (q);
  if (q->stop)
  {
    end_mutex (q);
    return (-1);
  }
  q->stop = 1;
  debug ("waiting on tasks to exit...\n");
  while (q->waiting || q->running)
  {
    set_ready (q);
    end_mutex (q);
    sleep (100);
    wait_mutex (q);
  }
  end_mutex (q);
  debug ("stop completed\n");
  return (0);
}
Пример #7
0
void *calloc(size_t nelem, size_t elsize)
{
	void *ptr = NULL;
#	ifdef SAFE
	wait_mutex(&malloc_mutex);
#	endif
	ptr =  _mem_alloc(nelem * elsize, 1);
#	ifdef SAFE
	leave_mutex(&malloc_mutex);
#	endif
	return ptr;
}
Пример #8
0
void *malloc(size_t size)
{
	void *ptr = NULL;
#	ifdef SAFE
	wait_mutex(&malloc_mutex);
#	endif
	ptr =  _mem_alloc(size, 0);
#	ifdef SAFE
	leave_mutex(&malloc_mutex);
#	endif
	return ptr;
}
Пример #9
0
/*
 * reset active tasks
 */
int task_reset (TASKQ *q)
{
  TASK *t;

  wait_mutex (q);
  while ((t = q->queue) != NULL)
  {
    q->queue = t->next;
    t->next = q->pool;
    q->pool = t;
  }
  end_mutex (q);
  return (0);
}
Пример #10
0
/*
 * start as many threads as might be needed for the current queue
 */
int task_start (TASKQ *q)
{
  int num_tasks = 0;
  TASK *t;

  wait_mutex (q);
  q->stop = 0;
  for (t = q->queue; t != NULL; t = t->next)
    num_tasks++;
  num_tasks -= q->waiting;
  set_ready (q);
  while ((num_tasks-- > 0) && (q->running < q->maxthreads))
  {
    debug ("starting new task\n");
    q->running++;
    t_start (task_run, q);
  }
  end_mutex (q);
  return (0);
}
Пример #11
0
struct stdfss_res *mkdevice(int wpid, struct working_thread *thread, struct stdfss_mkdevice *mkdevice_cmd)
{
	struct stdfss_res *ret = NULL;
	struct smount_info *minf = NULL;
	struct sdevice_info *opening_dinf = NULL;
	char *str = NULL, *strmatched = NULL;
	int parse_ret, dir_exists;
	struct gc_node *dir_base_node = NULL, *device_base_node = NULL;
	unsigned int *block = NULL;
	unsigned int nodeid;
	
	// get device file name from smo
	str = get_string(mkdevice_cmd->path_smo);
	
	ret = check_path(str, thread->command.command);
	if(ret != NULL) return ret;

	char *devstr = get_string(mkdevice_cmd->service_name);

	ret = check_path(devstr, thread->command.command);
	if(ret != NULL)
	{
		free(str);
		return ret;
	}

	// check path is ok
	if(str[len(str)] == '/')
	{
		free(str);
		free(devstr);
		return build_response_msg(thread->command.command, STDFSSERR_INVALID_COMMAND_PARAMS);
	}

	// get mount info
	wait_mutex(&mounted_mutex);
	minf = (struct smount_info *)lpt_getvalue_parcial_matchE(mounted, str, &strmatched);
	leave_mutex(&mounted_mutex);

	if(minf == NULL)
	{
		free(str);
		free(devstr);
		return build_response_msg(mkdevice_cmd->command, STDFSSERR_DEVICE_NOT_MOUNTED);
	}

	// check file does not exist
	parse_ret = parse_directory(TRUE, &dir_base_node, OFS_NODELOCK_EXCLUSIVE | OFS_NODELOCK_BLOCKING, thread->command.command, thread, wpid, minf, str, len(strmatched), NULL, &nodeid, NULL, &dir_exists, &ret);

	if(ret != NULL) free(ret);
	ret = NULL;

	if(parse_ret)
	{
		// file exists
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(strmatched);
		free(str);
		free(devstr);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, dir_base_node);
		return build_response_msg(thread->command.command, STDFSSERR_FILE_EXISTS);
	}

	if(!dir_exists)
	{
		// worng path
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(strmatched);
		free(str);
		free(devstr);
		return build_response_msg(thread->command.command, STDFSSERR_FILE_DOESNOTEXIST);
	}

	dir_base_node = nref(minf->dinf, thread->lastdir_parsed_node->nodeid);
	
	free(strmatched);

	// Create device file
	if(!create_file(dir_base_node, str, last_index_of(str, '/') + 1, OFS_DEVICE_FILE, TRUE, minf, wpid, thread->command.command, &nodeid, &device_base_node, OFS_NOFLAGS , &ret))
	{
		nfree(minf->dinf, thread->lastdir_parsed_node);
		nfree(minf->dinf, dir_base_node);
		thread->lastdir_parsed_node = NULL;
		
		free(str);
		free(devstr);
		return ret;
	}
	
	nfree(minf->dinf, thread->lastdir_parsed_node);
	nfree(minf->dinf, dir_base_node);
	thread->lastdir_parsed_node = NULL;
	
	// get a free block 
	block = get_free_blocks(1, TRUE, minf, thread->command.command, wpid, &ret);
	if(ret != NULL)
	{
		free(str);
		free(devstr);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, device_base_node);
		return ret;
	}

	free(str);

	clear_dir_buffer(thread->directory_buffer.buffer);

	// write buffer
	/*
		int LOGIC DEVICE ID: internal ID on the service (4 BYTES)
		int service name size; (4 BYTES)
		char SERVICE NAME[]: name of the device driver (zero terminated devstring) 
	*/
	*((unsigned int *)thread->directory_buffer.buffer) = (unsigned int)mkdevice_cmd->logic_deviceid;
	*((unsigned int *)(thread->directory_buffer.buffer + 4)) = len(devstr);
	mem_copy((unsigned char *)devstr, ((unsigned char *)thread->directory_buffer.buffer + 8), len(devstr) + 1);

	free(devstr);

	write_buffer((char *)thread->directory_buffer.buffer, OFS_DIR_BUFFERSIZE, *block, thread->command.command, wpid, minf, &ret);
	if(ret != NULL)
	{
		free_block(TRUE, TRUE, *block, minf, thread->command.command, wpid, &ret);
		free(block);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, device_base_node);
		return ret;
	}

	// update node
	device_base_node->n.file_size = 8 + len(devstr) + 1;
	device_base_node->n.blocks[0] = *block;

	if(!write_node(device_base_node, minf, wpid, thread->command.command, &ret) || ret != NULL)
	{
		free_block(TRUE, TRUE, *block, minf, thread->command.command, wpid, &ret);
		free(block);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, device_base_node);
		return ret;
	}

	nfree(minf->dinf, device_base_node);

	// unlock device node
	unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);	

	return build_response_msg(thread->command.command, STDFSSERR_OK);
}
Пример #12
0
void decrement_idle()
{
	wait_mutex(&idle_threads_mutex);
	idle_threads--;
	leave_mutex(&idle_threads_mutex);
}
Пример #13
0
void signal_idle()
{
	wait_mutex(&idle_threads_mutex);
	idle_threads++;
	leave_mutex(&idle_threads_mutex);
}
Пример #14
0
struct stdfss_res *mkdir(int wpid, struct working_thread *thread, struct stdfss_mkdir *mkdir_cmd)
{
	struct stdfss_res *ret = NULL;
	struct smount_info *minf = NULL;
	struct sdevice_info *opening_dinf = NULL;
	char *str = NULL, *old_str = NULL, *strmatched = NULL;
	int parse_ret, dir_exists;
	struct gc_node *dir_base_node = NULL, *new_dir_base_node = NULL;
	unsigned int nodeid;

	// get dir name from smo
	str = get_string(mkdir_cmd->dir_path);

	ret = check_path(str, thread->command.command);
	if(ret != NULL) return ret;

	// get mount info
	wait_mutex(&mounted_mutex);
	minf = (struct smount_info *)lpt_getvalue_parcial_matchE(mounted, str, &strmatched);
	leave_mutex(&mounted_mutex);

	if(minf == NULL)
	{
		ret = build_response_msg(mkdir_cmd->command, STDFSSERR_DEVICE_NOT_MOUNTED);
		free(str);
		return ret;
	}

	// remove trailing '/'
	if(str[len(str)] == '/')
	{
		old_str = str;
		str = substring(str, 0, len(str) - 1);
		free(old_str);
	}

	// check file does not exist
	parse_ret = parse_directory(TRUE, &dir_base_node, OFS_NODELOCK_EXCLUSIVE | OFS_NODELOCK_BLOCKING, thread->command.command, thread, wpid, minf, str, len(strmatched), NULL, &nodeid, NULL, &dir_exists, &ret);

	if(ret != NULL) free(ret);
	ret = NULL;

	free(strmatched);
	
	if(parse_ret)
	{
		// file exists
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(str);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, dir_base_node);
		return build_response_msg(thread->command.command, STDFSSERR_FILE_EXISTS);
	}
	if(!dir_exists)
	{
		// worng path
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(str);
		return build_response_msg(thread->command.command, STDFSSERR_FILE_DOESNOTEXIST);
	}

	dir_base_node = thread->lastdir_parsed_node;
	
	// Create directory file
	if(!create_file(dir_base_node, str, last_index_of(str, '/') + 1, OFS_DIRECTORY_FILE, TRUE, minf, wpid, thread->command.command, &nodeid, &new_dir_base_node , OFS_NOFLAGS, &ret))
	{
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(str);
		return ret;
	}

	nfree(minf->dinf, thread->lastdir_parsed_node);
	thread->lastdir_parsed_node = NULL;
	nfree(minf->dinf, new_dir_base_node);

	free(str);


	// unlock the dir node
	unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);

	return build_response_msg(thread->command.command, STDFSSERR_OK);
}