/**
 * receive message from given sender
 */
asmlinkage long sys_RcvMsg(pid_t *sender, void *msg, int *len, bool block){
	pid_t my_pid = current->pid;
	mailbox* mb = NULL;
	signal* signal = NULL;
	message* this_mail;
	pid_t *a_sender;
	void *a_msg;
	int *a_len;

	signal = get_signal(my_pid);
	if (signal == NULL) {
		signal = create_signal(my_pid, TRUE);
		wait_event(signal->wait_null, mb != NULL);
	}
	
	mb = get_mailbox(my_pid);
	
	if ((mb->stop) && (mb->size == 0))
		return MAILBOX_STOPPED;
	if ((block == NO_BLOCK) && (mb->size == 0))
		return MAILBOX_EMPTY;

	if ((block == BLOCK) && (mb->size == 0)) {
		wait_event(mb->wait_empty, mb->size != 0);
		printk("LLLLLLLLLLLOOOPPPP");
	}	
	spin_lock(&(mb->lock));
	this_mail = get_msg(&mb);
	spin_unlock(&(mb->lock));

	if (this_mail == NULL) return MAILBOX_ERROR;;

	a_sender = &(this_mail->sender);
	a_msg = this_mail->content;
	a_len = &(this_mail->len);

	if (((*a_len) > MAX_MSG_SIZE) || ((*a_len) < 0))
		return MSG_LENGTH_ERROR;

	if ((copy_to_user(sender, a_sender, sizeof(pid_t))))
		return MSG_ARG_ERROR;
	if ((copy_to_user(msg, a_msg, *a_len)))
		return MSG_ARG_ERROR;
	if ((copy_to_user(len, a_len, sizeof(int))))
		 return MSG_ARG_ERROR;

	spin_lock(&(mb->lock));
	rm_message(&mb);
	spin_unlock(&(mb->lock));

	//successful
	return 0;
}
Beispiel #2
0
static int dequeue_message(int for_proc, void *msg_data, size_t msg_size, void *session)
{
   int result, queue_lock_held = 0, read_partial_message;
   size_t bytes_read = 0, bytes_to_read, qsize, qbytes_read;
   unsigned char *read_from, *write_to;
   void *qdata;

   if (!has_message(for_proc, session))
      return 0;
   
   result = take_queue_lock(session);
   if (result == -1) {
      goto error;
   }
   queue_lock_held = 1;

   while (has_message(for_proc, session) && bytes_read < msg_size) {
      get_message(for_proc, &qdata, &qsize, &qbytes_read, session);
      
      read_partial_message = (qsize - qbytes_read) > (msg_size - bytes_read);
      read_from = ((unsigned char *) qdata) + qbytes_read;
      write_to = ((unsigned char *) msg_data) + bytes_read;
      if (read_partial_message)
         bytes_to_read = msg_size - bytes_read;
      else
         bytes_to_read = qsize - qbytes_read;
      
      memcpy(write_to, read_from, bytes_to_read);
      bytes_read += bytes_to_read;
      qbytes_read += bytes_to_read;
      update_bytes_read(for_proc, qbytes_read, session);
      
      if (!read_partial_message) {
         assert(qbytes_read == qsize);
         rm_message(for_proc, session);
      }
   }

   result = release_queue_lock(session);
   if (result == -1) {
      goto error;
   }
   queue_lock_held = 0;

   return bytes_read;

  error:

   if (queue_lock_held)
      release_queue_lock(session);
   return -1;
}