Beispiel #1
0
int msg_send_int(msg_t *m, kernel_pid_t target_pid)
{
#ifdef DEVELHELP
    if (!pid_is_valid(target_pid)) {
        DEBUG("msg_send(): target_pid is invalid, continuing anyways\n");
    }
#endif /* DEVELHELP */

    thread_t *target = (thread_t *) sched_threads[target_pid];

    if (target == NULL) {
        DEBUG("msg_send_int(): target thread does not exist\n");
        return -1;
    }

    m->sender_pid = KERNEL_PID_ISR;
    if (target->status == STATUS_RECEIVE_BLOCKED) {
        DEBUG("msg_send_int: Direct msg copy from %" PRIkernel_pid " to %"
              PRIkernel_pid ".\n", thread_getpid(), target_pid);


        /* copy msg to target */
        msg_t *target_message = (msg_t*) target->wait_data;
        *target_message = *m;
        sched_set_status(target, STATUS_PENDING);

        sched_context_switch_request = 1;
        return 1;
    }
    else {
        DEBUG("msg_send_int: Receiver not waiting.\n");
        return (queue_msg(target, m));
    }
}
Beispiel #2
0
int msg_send_int(msg_t *m, unsigned int target_pid)
{
    tcb_t *target = (tcb_t *) sched_threads[target_pid];

    if (target == NULL) {
        DEBUG("msg_send_int(): target thread does not exist\n");
        return -1;
    }

    if (target->status == STATUS_RECEIVE_BLOCKED) {
        DEBUG("msg_send_int: Direct msg copy from %i to %i.\n", thread_getpid(), target_pid);

        m->sender_pid = target_pid;

        /* copy msg to target */
        msg_t *target_message = (msg_t*) target->wait_data;
        *target_message = *m;
        sched_set_status(target, STATUS_PENDING);

        sched_context_switch_request = 1;
        return 1;
    }
    else {
        DEBUG("msg_send_int: Receiver not waiting.\n");
        return (queue_msg(target, m));
    }
}
Beispiel #3
0
static void
run_S_NEW(void)
{
    struct ofpbuf *buf = ofpraw_alloc(OFPRAW_NXT_TLV_TABLE_REQUEST,
                                      rconn_get_version(swconn), 0);
    xid = queue_msg(buf);
    state = S_TLV_TABLE_REQUESTED;
}
Beispiel #4
0
static void
get_switch_config(struct rconn *swconn)
{
    struct ofpbuf *request;

    request = ofpraw_alloc(OFPRAW_OFPT_GET_CONFIG_REQUEST,
                           rconn_get_version(swconn), 0);
    queue_msg(request);
}
Beispiel #5
0
int msg_send_to_self(msg_t *m)
{
    unsigned int state = disableIRQ();

    m->sender_pid = sched_active_pid;
    int res = queue_msg((tcb_t *) sched_active_thread, m);

    restoreIRQ(state);
    return res;
}
Beispiel #6
0
int msg_send_to_self(msg_t *m)
{
    unsigned state = irq_disable();

    m->sender_pid = sched_active_pid;
    int res = queue_msg((thread_t *) sched_active_thread, m);

    irq_restore(state);
    return res;
}
Beispiel #7
0
/*
 * shut_client()
 *	Shut down a connection from a client to a server
 */
void
shut_client(struct portref *pr, int sema_held)
{
	struct sysmsg *sm;
	struct port *port;
	ulong refs;

	/*
	 * Decrement the reference count, just return if
	 * it's not zero yet.
	 * TBD: consider compare-and-exchange
	 */
	p_lock_void(&pr->p_lock, SPL0);
	refs = pr->p_refs;
	pr->p_refs -= 1;
	v_lock(&pr->p_lock, SPL0_SAME);
	if (refs > 1) {
		if (sema_held) {
			v_sema(&pr->p_sema);
		}
		return;
	}

	/*
	 * Get a system message
	 */
	sm = MALLOC(sizeof(struct sysmsg), MT_SYSMSG);
	sm->sm_sender = pr;
	sm->sm_op = M_DISCONNECT;
	sm->sm_arg = (long)pr;
	sm->sm_arg1 = sm->sm_nseg = 0;

	/*
	 * If he's closed on us at the same time, no problem.
	 */
	p_lock_void(&pr->p_lock, SPL0);
	if (!(port = pr->p_port)) {
		v_lock(&pr->p_lock, SPL0_SAME);
		free_portref(pr);
		FREE(sm, MT_SYSMSG);
		return;
	}

	/*
	 * Put disconnect message on port's queue.  Flag that we've
	 * sent our final message.  He will clean up from here.
	 */
	pr->p_state = PS_CLOSING;
	queue_msg(port, sm, SPL0);
	if (!sema_held) {
		p_sema_v_lock(&pr->p_sema, PRIHI, &pr->p_lock);
	} else {
		v_lock(&pr->p_lock, SPL0_SAME);
	}
}
Beispiel #8
0
static void
set_switch_config(struct rconn *swconn, const struct ofp_switch_config *config)
{
    struct ofpbuf *request;

    request =
        ofpraw_alloc(OFPRAW_OFPT_SET_CONFIG, rconn_get_version(swconn), 0);
    ofpbuf_put(request, config, sizeof *config);

    queue_msg(request);
}
Beispiel #9
0
void
msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg,
						 gboolean queue)
{
	g_return_if_fail(swboard != NULL);
	g_return_if_fail(msg     != NULL);

	if (msn_switchboard_can_send(swboard))
		release_msg(swboard, msg);
	else if (queue)
		queue_msg(swboard, msg);
}
Beispiel #10
0
void
msn_switchboard_send_msg(MsnSwitchBoard *swboard, MsnMessage *msg,
						 gboolean queue)
{
	g_return_if_fail(swboard != NULL);
	g_return_if_fail(msg     != NULL);

	purple_debug_info("msn", "switchboard send msg..\n");
	if (msn_switchboard_can_send(swboard))
		release_msg(swboard, msg);
	else if (queue)
		queue_msg(swboard, msg);
}
/**
 * Called with any sensor list request received.
 *
 * Each time the function must call #GNUNET_CADET_receive_done on the channel
 * in order to receive the next message. This doesn't need to be immediate:
 * can be delayed if some processing is done on the message.
 *
 * @param cls Closure (set from #GNUNET_CADET_connect).
 * @param channel Connection to the other end.
 * @param channel_ctx Place to store local state associated with the channel.
 * @param message The actual message.
 * @return #GNUNET_OK to keep the channel open,
 *         #GNUNET_SYSERR to close it (signal serious error).
 */
static int
handle_sensor_list_req (void *cls, struct GNUNET_CADET_Channel *channel,
                        void **channel_ctx,
                        const struct GNUNET_MessageHeader *message)
{
  struct ClientPeerContext *cp = *channel_ctx;
  struct GNUNET_MessageHeader *end_msg;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received a sensor list request from peer `%s'.\n",
              GNUNET_i2s (&cp->peerid));
  GNUNET_CONTAINER_multihashmap_iterate (sensors, &send_sensor_brief, cp);
  end_msg = GNUNET_new (struct GNUNET_MessageHeader);

  end_msg->size = htons (sizeof (struct GNUNET_MessageHeader));
  end_msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_END);
  queue_msg (end_msg, cp);
  GNUNET_CADET_receive_done (channel);
  return GNUNET_OK;
}
/**
 * Called with any request for full sensor information.
 *
 * Each time the function must call #GNUNET_CADET_receive_done on the channel
 * in order to receive the next message. This doesn't need to be immediate:
 * can be delayed if some processing is done on the message.
 *
 * @param cls Closure (set from #GNUNET_CADET_connect).
 * @param channel Connection to the other end.
 * @param channel_ctx Place to store local state associated with the channel.
 * @param message The actual message.
 * @return #GNUNET_OK to keep the channel open,
 *         #GNUNET_SYSERR to close it (signal serious error).
 */
static int
handle_sensor_full_req (void *cls, struct GNUNET_CADET_Channel *channel,
                        void **channel_ctx,
                        const struct GNUNET_MessageHeader *message)
{
  struct ClientPeerContext *cp = *channel_ctx;
  struct GNUNET_SENSOR_SensorBriefMessage *sbm = NULL;
  struct GNUNET_SENSOR_SensorFullMessage *sfm;
  uint16_t msg_size;
  uint16_t sensorname_size;

  msg_size = ntohs (message->size);
  /* parse & error check */
  if (msg_size > sizeof (struct GNUNET_SENSOR_SensorBriefMessage))
  {
    sbm = (struct GNUNET_SENSOR_SensorBriefMessage *) message;
    sensorname_size = ntohs (sbm->name_size);
    if (msg_size !=
        sizeof (struct GNUNET_SENSOR_SensorBriefMessage) + sensorname_size)
      sbm = NULL;
  }
  if (NULL == sbm)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Received an invalid full sensor request from peer `%s'.\n",
                GNUNET_i2s (&cp->peerid));
    return GNUNET_SYSERR;
  }
  /* Create and send msg with full sensor info */
  sfm = create_full_sensor_msg ((char *) &sbm[1]);
  if (NULL == sfm)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Error creating full sensor info msg for sensor `%s'.\n",
                (char *) &sbm[1]);
    return GNUNET_SYSERR;
  }
  queue_msg ((struct GNUNET_MessageHeader *) sfm, cp);
  GNUNET_CADET_receive_done (channel);
  return GNUNET_OK;
}
/**
 * Iterate over defined sensors, creates and sends brief sensor information to
 * given client peer over CADET.
 *
 * @param cls closure, the client peer
 * @param key sensor key
 * @param value sensor value
 * @return #GNUNET_YES to continue iteration
 */
static int
send_sensor_brief (void *cls, const struct GNUNET_HashCode *key, void *value)
{
  struct ClientPeerContext *cp = cls;
  struct GNUNET_SENSOR_SensorInfo *sensor = value;
  struct GNUNET_SENSOR_SensorBriefMessage *msg;
  uint16_t sensorname_size;
  uint16_t total_size;

  /* Create message struct */
  sensorname_size = strlen (sensor->name) + 1;
  total_size =
      sizeof (struct GNUNET_SENSOR_SensorBriefMessage) + sensorname_size;
  msg = GNUNET_malloc (total_size);
  msg->header.size = htons (total_size);
  msg->header.type = htons (GNUNET_MESSAGE_TYPE_SENSOR_BRIEF);
  msg->name_size = htons (sensorname_size);
  msg->version_major = htons (sensor->version_major);
  msg->version_minor = htons (sensor->version_minor);
  memcpy (&msg[1], sensor->name, sensorname_size);
  /* Queue the msg */
  queue_msg ((struct GNUNET_MessageHeader *) msg, cp);
  return GNUNET_YES;
}
Beispiel #14
0
int msg_send(msg_t *m, unsigned int target_pid, bool block)
{
    if (inISR()) {
        return msg_send_int(m, target_pid);
    }

    if ((unsigned int)sched_active_pid == target_pid) {
        return msg_send_to_self(m);
    }

    dINT();

    tcb_t *target = (tcb_t*) sched_threads[target_pid];

    m->sender_pid = sched_active_pid;

    if (target == NULL) {
        DEBUG("msg_send(): target thread does not exist\n");
        eINT();
        return -1;
    }

    DEBUG("msg_send() %s:%i: Sending from %i to %i. block=%i src->state=%i target->state=%i\n", __FILE__, __LINE__, sched_active_pid, target_pid, block, sched_active_thread->status, target->status);

    if (target->status != STATUS_RECEIVE_BLOCKED) {
        DEBUG("msg_send() %s:%i: Target %i is not RECEIVE_BLOCKED.\n", __FILE__, __LINE__, target_pid);
        if (target->msg_array && queue_msg(target, m)) {
            DEBUG("msg_send() %s:%i: Target %i has a msg_queue. Queueing message.\n", __FILE__, __LINE__, target_pid);
            eINT();
            if (sched_active_thread->status == STATUS_REPLY_BLOCKED) {
                thread_yield();
            }
            return 1;
        }

        if (!block) {
            DEBUG("msg_send: %s: Receiver not waiting, block=%u\n", sched_active_thread->name, block);
            eINT();
            return 0;
        }

        DEBUG("msg_send: %s: send_blocked.\n", sched_active_thread->name);
        queue_node_t n;
        n.priority = sched_active_thread->priority;
        n.data = (unsigned int) sched_active_thread;
        n.next = NULL;
        DEBUG("msg_send: %s: Adding node to msg_waiters:\n", sched_active_thread->name);

        queue_priority_add(&(target->msg_waiters), &n);

        sched_active_thread->wait_data = (void*) m;

        int newstatus;

        if (sched_active_thread->status == STATUS_REPLY_BLOCKED) {
            newstatus = STATUS_REPLY_BLOCKED;
        }
        else {
            newstatus = STATUS_SEND_BLOCKED;
        }

        sched_set_status((tcb_t*) sched_active_thread, newstatus);

        DEBUG("msg_send: %s: Back from send block.\n", sched_active_thread->name);
    }
    else {
        DEBUG("msg_send: %s: Direct msg copy from %i to %i.\n", sched_active_thread->name, thread_getpid(), target_pid);
        /* copy msg to target */
        msg_t *target_message = (msg_t*) target->wait_data;
        *target_message = *m;
        sched_set_status(target, STATUS_PENDING);
    }

    eINT();
    thread_yield();

    return 1;
}
Beispiel #15
0
static int _msg_send(msg_t *m, kernel_pid_t target_pid, bool block, unsigned state)
{
#ifdef DEVELHELP
    if (!pid_is_valid(target_pid)) {
        DEBUG("msg_send(): target_pid is invalid, continuing anyways\n");
    }
#endif /* DEVELHELP */

    thread_t *target = (thread_t*) sched_threads[target_pid];

    m->sender_pid = sched_active_pid;

    if (target == NULL) {
        DEBUG("msg_send(): target thread does not exist\n");
        irq_restore(state);
        return -1;
    }

    thread_t *me = (thread_t *) sched_active_thread;

    DEBUG("msg_send() %s:%i: Sending from %" PRIkernel_pid " to %" PRIkernel_pid
          ". block=%i src->state=%i target->state=%i\n", RIOT_FILE_RELATIVE,
          __LINE__, sched_active_pid, target_pid,
          block, me->status, target->status);

    if (target->status != STATUS_RECEIVE_BLOCKED) {
        DEBUG("msg_send() %s:%i: Target %" PRIkernel_pid " is not RECEIVE_BLOCKED.\n",
              RIOT_FILE_RELATIVE, __LINE__, target_pid);

        if (queue_msg(target, m)) {
            DEBUG("msg_send() %s:%i: Target %" PRIkernel_pid
                  " has a msg_queue. Queueing message.\n", RIOT_FILE_RELATIVE,
                  __LINE__, target_pid);
            irq_restore(state);
            if (me->status == STATUS_REPLY_BLOCKED) {
                thread_yield_higher();
            }
            return 1;
        }

        if (!block) {
            DEBUG("msg_send: %" PRIkernel_pid ": Receiver not waiting, block=%u\n",
                  me->pid, block);
            irq_restore(state);
            return 0;
        }

        DEBUG("msg_send: %" PRIkernel_pid ": going send blocked.\n",
              me->pid);

        me->wait_data = (void*) m;

        int newstatus;

        if (me->status == STATUS_REPLY_BLOCKED) {
            newstatus = STATUS_REPLY_BLOCKED;
        }
        else {
            newstatus = STATUS_SEND_BLOCKED;
        }

        sched_set_status((thread_t*) me, newstatus);

        thread_add_to_list(&(target->msg_waiters), me);

        irq_restore(state);
        thread_yield_higher();

        DEBUG("msg_send: %" PRIkernel_pid ": Back from send block.\n",
              me->pid);
    }
    else {
        DEBUG("msg_send: %" PRIkernel_pid ": Direct msg copy from %"
              PRIkernel_pid " to %" PRIkernel_pid ".\n",
              me->pid, thread_getpid(), target_pid);
        /* copy msg to target */
        msg_t *target_message = (msg_t*) target->wait_data;
        *target_message = *m;
        sched_set_status(target, STATUS_PENDING);

        irq_restore(state);
        thread_yield_higher();
    }

    return 1;
}
Beispiel #16
0
int msg_send(msg_t *m, unsigned int target_pid, bool block)
{
    if(inISR()) {
        return msg_send_int(m, target_pid);
    }

    tcb_t *target = (tcb_t*) sched_threads[target_pid];

    m->sender_pid = thread_pid;

    if(m->sender_pid == target_pid) {
        return -1;
    }

    if(target == NULL) {
        return -1;
    }

    dINT();

    if(target->status !=  STATUS_RECEIVE_BLOCKED) {
        if(target->msg_array && queue_msg(target, m)) {
            eINT();
            return 1;
        }

        if(!block) {
            DEBUG("%s: receiver not waiting. block=%u\n", active_thread->name, block);
            eINT();
            return 0;
        }

        DEBUG("%s: send_blocked.\n", active_thread->name);
        queue_node_t n;
        n.priority = active_thread->priority;
        n.data = (unsigned int) active_thread;
        DEBUG("%s: Adding node to msg_waiters:\n", active_thread->name);

        queue_priority_add(&(target->msg_waiters), &n);

        active_thread->wait_data = (void*) m;

        int newstatus;

        if(active_thread->status == STATUS_REPLY_BLOCKED) {
            newstatus = STATUS_REPLY_BLOCKED;
        }
        else {
            newstatus = STATUS_SEND_BLOCKED;
        }

        sched_set_status((tcb_t*) active_thread,  newstatus);

        DEBUG("%s: back from send block.\n", active_thread->name);
    }
    else {
        DEBUG("%s: direct msg copy.\n", active_thread->name);
        /* copy msg to target */
        msg_t *target_message = (msg_t*) target->wait_data;
        *target_message = *m;
        sched_set_status(target,  STATUS_PENDING);
    }

    eINT();
    thread_yield();

    return 1;
}