static void
receive_completed (IrisArbiter  *arbiter,
                   IrisReceiver *receiver)
{
	IrisCoordinationArbiter        *coord;
	IrisCoordinationArbiterPrivate *priv;
	IrisReceiver                   *resume = NULL;

	g_return_if_fail (IRIS_IS_COORDINATION_ARBITER (arbiter));
	g_return_if_fail (IRIS_IS_RECEIVER (receiver));

	coord = IRIS_COORDINATION_ARBITER (arbiter);
	priv = coord->priv;

	g_static_rec_mutex_lock (&priv->mutex);

	if (g_atomic_int_dec_and_test ((gint*)&priv->active)) {
		if (priv->flags & IRIS_COORD_COMPLETE) {
		}
		else if (priv->flags & IRIS_COORD_CONCURRENT) {
			if (priv->flags & IRIS_COORD_NEEDS_EXCLUSIVE) {
				priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_EXCLUSIVE);
				priv->flags |= IRIS_COORD_EXCLUSIVE;
				resume = priv->exclusive;
			}
			else if (priv->flags & IRIS_COORD_NEEDS_TEARDOWN) {
				priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_TEARDOWN);
				priv->flags |= IRIS_COORD_TEARDOWN;
				resume = priv->teardown;
			}
			else if (!priv->concurrent->priv->active) {
				resume = priv->concurrent;
			}
		}
		else if (priv->flags & IRIS_COORD_EXCLUSIVE) {
			if (priv->flags & IRIS_COORD_NEEDS_EXCLUSIVE) {
				/* Try to save mode switches by running exclusive now
				 * regardless of what other modes want to run. */
				resume = priv->exclusive;
			}
			else if (priv->flags & IRIS_COORD_NEEDS_CONCURRENT) {
				priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_CONCURRENT);
				priv->flags |= IRIS_COORD_CONCURRENT;
				resume = priv->concurrent;
			}
			else if (priv->flags & IRIS_COORD_NEEDS_TEARDOWN) {
				priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_TEARDOWN);
				priv->flags |= IRIS_COORD_TEARDOWN;
				resume = priv->teardown;
			}
			else if (!priv->exclusive->priv->active) {
				resume = priv->exclusive;
			}
		}
		else if (priv->flags & IRIS_COORD_TEARDOWN) {
			if ((priv->flags & IRIS_COORD_COMPLETE) == 0) {
				priv->flags &= ~IRIS_COORD_NEEDS_TEARDOWN;
				resume = priv->teardown;
			}
		}
		else {
			g_warn_if_reached ();
		}
	}

	g_static_rec_mutex_unlock (&priv->mutex);

	if (resume)
		iris_receiver_resume (resume);
}
Exemple #2
0
GstFlowReturn
gst_swfdec_chain (GstPad * pad, GstBuffer * buffer)
{
  GstFlowReturn res = GST_FLOW_OK;
  int ret;
  GstSwfdec *swfdec = GST_SWFDEC (GST_PAD_PARENT (pad));

  g_static_rec_mutex_lock (&swfdec->mutex);
  GST_DEBUG_OBJECT (swfdec, "about to call swfdec_decoder_parse");
  ret = swfdec_decoder_parse (swfdec->decoder);
  if (ret == SWF_NEEDBITS) {
    guint buf_size;
    GstBuffer *prev_buffer;

    GST_DEBUG_OBJECT (swfdec, "SWF_NEEDBITS, feeding data to swfdec-decoder");
    buf_size = gst_adapter_available (swfdec->adapter);
    if (buf_size) {
      prev_buffer = gst_buffer_new_and_alloc (buf_size);
      memcpy (GST_BUFFER_DATA (prev_buffer), gst_adapter_peek (swfdec->adapter,
              buf_size), buf_size);
      gst_adapter_flush (swfdec->adapter, buf_size);

      swfdec_decoder_add_buffer (swfdec->decoder,
          gst_swfdec_buffer_to_swf (prev_buffer));
    }

    swfdec_decoder_add_buffer (swfdec->decoder,
        gst_swfdec_buffer_to_swf (buffer));

  } else if (ret == SWF_CHANGE) {

    GstCaps *caps;
    double rate;

    GstTagList *taglist;

    GST_DEBUG_OBJECT (swfdec, "SWF_CHANGE");
    gst_adapter_push (swfdec->adapter, buffer);

    swfdec_decoder_get_image_size (swfdec->decoder,
        &swfdec->width, &swfdec->height);
    swfdec_decoder_get_rate (swfdec->decoder, &rate);
    swfdec->interval = GST_SECOND / rate;

    swfdec->frame_rate_n = (int) (rate * 256.0);
    swfdec->frame_rate_d = 256;

    caps = gst_caps_copy (gst_pad_get_pad_template_caps (swfdec->videopad));
    gst_caps_set_simple (caps,
        "framerate", GST_TYPE_FRACTION, swfdec->frame_rate_n,
        swfdec->frame_rate_d, "height", G_TYPE_INT, swfdec->height, "width",
        G_TYPE_INT, swfdec->width, NULL);
    if (gst_pad_set_caps (swfdec->videopad, caps)) {
      /* good */
    } else {
      gst_caps_unref (caps);
      GST_ELEMENT_ERROR (swfdec, CORE, NEGOTIATION, (NULL), (NULL));
      res = GST_FLOW_ERROR;
      goto done;
    }
    gst_caps_unref (caps);

    caps = gst_caps_copy (gst_pad_get_pad_template_caps (swfdec->audiopad));
    if (gst_pad_set_caps (swfdec->audiopad, caps)) {
      swfdec->have_format = TRUE;
    } else {
      gst_caps_unref (caps);
      GST_ELEMENT_ERROR (swfdec, CORE, NEGOTIATION, (NULL), (NULL));
      res = GST_FLOW_ERROR;
      goto done;
    }

    gst_caps_unref (caps);


    taglist = gst_tag_list_new ();
    gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE,
        GST_TAG_ENCODER_VERSION, swfdec_decoder_get_version (swfdec->decoder),
        NULL);
    gst_element_found_tags (GST_ELEMENT (swfdec), taglist);
  } else if (ret == SWF_EOF) {
    GST_DEBUG_OBJECT (swfdec, "SWF_EOF");
    gst_swfdec_render (swfdec, ret);
    gst_task_start (swfdec->task);
  }

done:
  g_static_rec_mutex_unlock (&swfdec->mutex);
  return res;

}
static gboolean
gst_decklink_src_start (GstElement * element)
{
  GstDecklinkSrc *decklinksrc = GST_DECKLINK_SRC (element);
  DeckLinkCaptureDelegate *delegate;
  //IDeckLinkDisplayModeIterator *mode_iterator;
  //IDeckLinkDisplayMode *mode;
  BMDAudioSampleType sample_depth;
  int channels;
  HRESULT ret;
  const GstDecklinkMode *mode;
  IDeckLinkConfiguration *config;
  BMDVideoConnection conn;
  BMDAudioConnection aconn;

  GST_DEBUG_OBJECT (decklinksrc, "start");

  decklinksrc->decklink = gst_decklink_get_nth_device (decklinksrc->device);
  if (decklinksrc->decklink == NULL) {
    return FALSE;
  }

  ret = decklinksrc->decklink->QueryInterface (IID_IDeckLinkInput,
      (void **) &decklinksrc->input);
  if (ret != S_OK) {
    GST_ERROR ("selected device does not have input interface");
    return FALSE;
  }

  delegate = new DeckLinkCaptureDelegate ();
  delegate->priv = decklinksrc;
  decklinksrc->input->SetCallback (delegate);

  ret = decklinksrc->decklink->QueryInterface (IID_IDeckLinkConfiguration,
      (void **) &config);
  if (ret != S_OK) {
    GST_ERROR ("query interface failed");
    return FALSE;
  }

  switch (decklinksrc->connection) {
    default:
    case GST_DECKLINK_CONNECTION_SDI:
      conn = bmdVideoConnectionSDI;
      aconn = bmdAudioConnectionEmbedded;
      break;
    case GST_DECKLINK_CONNECTION_HDMI:
      conn = bmdVideoConnectionHDMI;
      aconn = bmdAudioConnectionEmbedded;
      break;
    case GST_DECKLINK_CONNECTION_OPTICAL_SDI:
      conn = bmdVideoConnectionOpticalSDI;
      aconn = bmdAudioConnectionEmbedded;
      break;
    case GST_DECKLINK_CONNECTION_COMPONENT:
      conn = bmdVideoConnectionComponent;
      aconn = bmdAudioConnectionAnalog;
      break;
    case GST_DECKLINK_CONNECTION_COMPOSITE:
      conn = bmdVideoConnectionComposite;
      aconn = bmdAudioConnectionAnalog;
      break;
    case GST_DECKLINK_CONNECTION_SVIDEO:
      conn = bmdVideoConnectionSVideo;
      aconn = bmdAudioConnectionAnalog;
      break;
  }

  ret = config->SetInt (bmdDeckLinkConfigVideoInputConnection, conn);
  if (ret != S_OK) {
    GST_ERROR ("set configuration (input source)");
    return FALSE;
  }

  if (decklinksrc->connection == GST_DECKLINK_CONNECTION_COMPOSITE) {
    ret = config->SetInt (bmdDeckLinkConfigAnalogVideoInputFlags,
        bmdAnalogVideoFlagCompositeSetup75);
    if (ret != S_OK) {
      GST_ERROR ("set configuration (composite setup)");
      return FALSE;
    }
  }

  switch (decklinksrc->audio_connection) {
    default:
    case GST_DECKLINK_AUDIO_CONNECTION_AUTO:
      break;
    case GST_DECKLINK_AUDIO_CONNECTION_EMBEDDED:
      aconn = bmdAudioConnectionEmbedded;
      break;
    case GST_DECKLINK_AUDIO_CONNECTION_AES_EBU:
      aconn = bmdAudioConnectionAESEBU;
      break;
    case GST_DECKLINK_AUDIO_CONNECTION_ANALOG:
      aconn = bmdAudioConnectionAnalog;
      break;
  }
  ret = config->SetInt (bmdDeckLinkConfigAudioInputConnection, aconn);
  if (ret != S_OK) {
    GST_ERROR ("set configuration (audio input connection)");
    return FALSE;
  }
#if 0
  ret = decklinksrc->input->GetDisplayModeIterator (&mode_iterator);
  if (ret != S_OK) {
    GST_ERROR ("failed to get display mode iterator");
    return FALSE;
  }

  i = 0;
  while (mode_iterator->Next (&mode) == S_OK) {
    const char *mode_name;

    mode->GetName (&mode_name);

    GST_DEBUG ("%d: mode name: %s", i, mode_name);

    mode->Release ();
    i++;
  }
#endif

  mode = gst_decklink_get_mode (decklinksrc->mode);

  ret = decklinksrc->input->EnableVideoInput (mode->mode, bmdFormat8BitYUV, 0);
  if (ret != S_OK) {
    GST_ERROR ("enable video input failed");
    return FALSE;
  }

  sample_depth = bmdAudioSampleType16bitInteger;
  channels = 2;
  ret = decklinksrc->input->EnableAudioInput (bmdAudioSampleRate48kHz,
      sample_depth, channels);
  if (ret != S_OK) {
    GST_ERROR ("enable video input failed");
    return FALSE;
  }

  ret = decklinksrc->input->StartStreams ();
  if (ret != S_OK) {
    GST_ERROR ("start streams failed");
    return FALSE;
  }

  g_static_rec_mutex_lock (&decklinksrc->task_mutex);
  gst_task_start (decklinksrc->task);
  g_static_rec_mutex_unlock (&decklinksrc->task_mutex);

  return TRUE;
}
static gboolean
gst_decklink_src_start (GstElement * element)
{
  GstDecklinkSrc *decklinksrc = GST_DECKLINK_SRC (element);
  DeckLinkCaptureDelegate *delegate;
  BMDAudioSampleType sample_depth;
  int channels;
  HRESULT ret;
  const GstDecklinkMode *mode;
  IDeckLinkConfiguration *config;
  BMDVideoConnection conn;
  BMDAudioConnection aconn;

  GST_DEBUG_OBJECT (decklinksrc, "start");

  decklinksrc->decklink = gst_decklink_get_nth_device (decklinksrc->device);
  if (decklinksrc->decklink == NULL) {
    return FALSE;
  }

  decklinksrc->input = gst_decklink_get_nth_input (decklinksrc->device);

  delegate = new DeckLinkCaptureDelegate ();
  delegate->priv = decklinksrc;
  ret = decklinksrc->input->SetCallback (delegate);
  if (ret != S_OK) {
    GST_ERROR ("set callback failed (input source)");
    return FALSE;
  }

  decklinksrc->config = gst_decklink_get_nth_config (decklinksrc->device);
  config = decklinksrc->config;

  switch (decklinksrc->connection) {
    default:
    case GST_DECKLINK_CONNECTION_SDI:
      conn = bmdVideoConnectionSDI;
      aconn = bmdAudioConnectionEmbedded;
      break;
    case GST_DECKLINK_CONNECTION_HDMI:
      conn = bmdVideoConnectionHDMI;
      aconn = bmdAudioConnectionEmbedded;
      break;
    case GST_DECKLINK_CONNECTION_OPTICAL_SDI:
      conn = bmdVideoConnectionOpticalSDI;
      aconn = bmdAudioConnectionEmbedded;
      break;
    case GST_DECKLINK_CONNECTION_COMPONENT:
      conn = bmdVideoConnectionComponent;
      aconn = bmdAudioConnectionAnalog;
      break;
    case GST_DECKLINK_CONNECTION_COMPOSITE:
      conn = bmdVideoConnectionComposite;
      aconn = bmdAudioConnectionAnalog;
      break;
    case GST_DECKLINK_CONNECTION_SVIDEO:
      conn = bmdVideoConnectionSVideo;
      aconn = bmdAudioConnectionAnalog;
      break;
  }

  ret = config->SetInt (bmdDeckLinkConfigVideoInputConnection, conn);
  if (ret != S_OK) {
    GST_ERROR ("set configuration (input source)");
    return FALSE;
  }

  if (decklinksrc->connection == GST_DECKLINK_CONNECTION_COMPOSITE) {
    ret = config->SetInt (bmdDeckLinkConfigAnalogVideoInputFlags,
        bmdAnalogVideoFlagCompositeSetup75);
    if (ret != S_OK) {
      GST_ERROR ("set configuration (composite setup)");
      return FALSE;
    }
  }

  switch (decklinksrc->audio_connection) {
    default:
    case GST_DECKLINK_AUDIO_CONNECTION_AUTO:
      /* set above */
      break;
    case GST_DECKLINK_AUDIO_CONNECTION_EMBEDDED:
      aconn = bmdAudioConnectionEmbedded;
      break;
    case GST_DECKLINK_AUDIO_CONNECTION_AES_EBU:
      aconn = bmdAudioConnectionAESEBU;
      break;
    case GST_DECKLINK_AUDIO_CONNECTION_ANALOG:
      aconn = bmdAudioConnectionAnalog;
      break;
  }
  ret = config->SetInt (bmdDeckLinkConfigAudioInputConnection, aconn);
  if (ret != S_OK) {
    GST_ERROR ("set configuration (audio input connection)");
    return FALSE;
  }

  mode = gst_decklink_get_mode (decklinksrc->mode);

  ret = decklinksrc->input->EnableVideoInput (mode->mode, bmdFormat8BitYUV, 0);
  if (ret != S_OK) {
    GST_ERROR ("enable video input failed");
    return FALSE;
  }

  sample_depth = bmdAudioSampleType16bitInteger;
  channels = 2;
  ret = decklinksrc->input->EnableAudioInput (bmdAudioSampleRate48kHz,
      sample_depth, channels);
  if (ret != S_OK) {
    GST_ERROR ("enable video input failed");
    return FALSE;
  }

  ret = decklinksrc->input->StartStreams ();
  if (ret != S_OK) {
    GST_ERROR ("start streams failed");
    return FALSE;
  }

  g_static_rec_mutex_lock (&decklinksrc->task_mutex);
  gst_task_start (decklinksrc->task);
  g_static_rec_mutex_unlock (&decklinksrc->task_mutex);

  return TRUE;
}
Exemple #5
0
/**
 * oh_load_plugin
 * @plugin_name: name of plugin to be loaded (e.g. "libdummy").
 *
 * Load plugin by name
 *
 * Returns: 0 on Success.
 **/
int oh_load_plugin(char *plugin_name)
{

        struct oh_plugin *plugin = NULL;
        struct oh_static_plugin *p = static_plugins;
        int err;

        if (!plugin_name) {
                err("ERROR. NULL plugin name passed.");
                return -1;
        }

        if (oh_init_ltdl()) {
                err("ERROR. Could not initialize ltdl for loading plugins.");
                return -1;
        }

        plugin = oh_get_plugin(plugin_name);
        if (plugin) {
                oh_release_plugin(plugin);
                dbg("Plugin %s already loaded. Not loading twice.",
                    plugin_name);
                return 0;
        }

        plugin = (struct oh_plugin *)g_malloc0(sizeof(struct oh_plugin));
        if (!plugin) {
                err("Out of memory.");
                return -1;
        }
        plugin->name = g_strdup(plugin_name);
        plugin->handler_count = 0;
        plugin->refcount = 0;
        g_static_rec_mutex_init(&plugin->lock);
        g_static_rec_mutex_init(&plugin->refcount_lock);

        /* first take search plugin in the array of static plugin */
        while (p->name) {
                if (!strcmp(plugin->name, p->name)) {
                        plugin->dl_handle = 0;
                        err = (*p->get_interface)((void **)&plugin->abi, UUID_OH_ABI_V2);

                        if (err < 0 || !plugin->abi || !plugin->abi->open) {
                                err("Can not get ABI V2");
                                goto cleanup_and_quit;
                        }

                        dbg("found static plugin %s", p->name);

                        g_static_rec_mutex_lock(&oh_plugins.lock);
                        oh_plugins.list = g_slist_append(oh_plugins.list, plugin);
                        g_static_rec_mutex_unlock(&oh_plugins.lock);

                        return 0;
                }
                p++;
        }

        plugin->dl_handle = lt_dlopenext(plugin->name);
        if (plugin->dl_handle == NULL) {
                err("Can not open %s plugin: %s", plugin->name, lt_dlerror());
                goto cleanup_and_quit;
        }

        err = oh_load_plugin_functions(plugin, &plugin->abi);

        if (err < 0 || !plugin->abi || !plugin->abi->open) {
                err("Can not get ABI");
                goto cleanup_and_quit;
        }
        g_static_rec_mutex_lock(&oh_plugins.lock);
        oh_plugins.list = g_slist_append(oh_plugins.list, plugin);
        g_static_rec_mutex_unlock(&oh_plugins.lock);

        return 0;
cleanup_and_quit:
        __delete_plugin(plugin);
        return -1;
}
static int 
_recv_message_fragment (lcm_udpm_t *lcm, lcm_buf_t *lcmb, uint32_t sz)
{
    lcm2_header_long_t *hdr = (lcm2_header_long_t*) lcmb->buf;

    // any existing fragment buffer for this message source?
    lcm_frag_buf_t *fbuf = lcm_frag_buf_store_lookup(lcm->frag_bufs,
            &lcmb->from);

    uint32_t msg_seqno = ntohl (hdr->msg_seqno);
    uint32_t data_size = ntohl (hdr->msg_size);
    uint32_t fragment_offset = ntohl (hdr->fragment_offset);
//    uint16_t fragment_no = ntohs (hdr->fragment_no);
    uint16_t fragments_in_msg = ntohs (hdr->fragments_in_msg);
    uint32_t frag_size = sz - sizeof (lcm2_header_long_t);
    char *data_start = (char*) (hdr + 1);

    // discard any stale fragments from previous messages
    if (fbuf && ((fbuf->msg_seqno != msg_seqno) ||
                 (fbuf->data_size != data_size))) {
        lcm_frag_buf_store_remove (lcm->frag_bufs, fbuf);
        dbg(DBG_LCM, "Dropping message (missing %d fragments)\n",
            fbuf->fragments_remaining);
        fbuf = NULL;
    }

//    printf ("fragment %d/%d (offset %d/%d) seq %d packet sz: %d %p\n",
//        ntohs(hdr->fragment_no) + 1, fragments_in_msg,
//        fragment_offset, data_size, msg_seqno, sz, fbuf);

    if (data_size > LCM_MAX_MESSAGE_SIZE) {
        dbg (DBG_LCM, "rejecting huge message (%d bytes)\n", data_size);
        return 0;
    }

    // create a new fragment buffer if necessary
    if (!fbuf && hdr->fragment_no == 0) {
        char *channel = (char*) (hdr + 1);
        int channel_sz = strlen (channel);
        if (channel_sz > LCM_MAX_CHANNEL_NAME_LENGTH) {
            dbg (DBG_LCM, "bad channel name length\n");
            lcm->udp_discarded_bad++;
            return 0;
        }

        // if the packet has no subscribers, drop the message now.
        if(!lcm_has_handlers(lcm->lcm, channel))
            return 0;

        fbuf = lcm_frag_buf_new (*((struct sockaddr_in*) &lcmb->from),
                channel, msg_seqno, data_size, fragments_in_msg,
                lcmb->recv_utime);
        lcm_frag_buf_store_add (lcm->frag_bufs, fbuf);
        data_start += channel_sz + 1;
        frag_size -= (channel_sz + 1);
    }

    if (!fbuf) return 0;

#ifdef __linux__
    if(lcm->kernel_rbuf_sz < 262145 && 
       data_size > lcm->kernel_rbuf_sz &&
       ! lcm->warned_about_small_kernel_buf) {
        fprintf(stderr, 
"==== LCM Warning ===\n"
"LCM detected that large packets are being received, but the kernel UDP\n"
"receive buffer is very small.  The possibility of dropping packets due to\n"
"insufficient buffer space is very high.\n"
"\n"
"For more information, visit:\n"
"   http://lcm-proj.github.io/multicast_setup.html\n\n");
        lcm->warned_about_small_kernel_buf = 1;
    }
#endif

    if (fragment_offset + frag_size > fbuf->data_size) {
        dbg (DBG_LCM, "dropping invalid fragment (off: %d, %d / %d)\n",
                fragment_offset, frag_size, fbuf->data_size);
        lcm_frag_buf_store_remove (lcm->frag_bufs, fbuf);
        return 0;
    }

    // copy data
    memcpy (fbuf->data + fragment_offset, data_start, frag_size);
    fbuf->last_packet_utime = lcmb->recv_utime;

    fbuf->fragments_remaining --;

    if (0 == fbuf->fragments_remaining) {
        // complete message received.  Is there a subscriber that still
        // wants it?  (i.e., does any subscriber have space in its queue?)
        if(!lcm_try_enqueue_message(lcm->lcm, fbuf->channel)) {
            // no... sad... free the fragment buffer and return
            lcm_frag_buf_store_remove (lcm->frag_bufs, fbuf);
            return 0;
        }

        // yes, transfer the message into the lcm_buf_t

        // deallocate the ringbuffer-allocated buffer
        g_static_rec_mutex_lock (&lcm->mutex);
        lcm_buf_free_data(lcmb, lcm->ringbuf);
        g_static_rec_mutex_unlock (&lcm->mutex);

        // transfer ownership of the message's payload buffer
        lcmb->buf = fbuf->data;
        fbuf->data = NULL;

        strcpy (lcmb->channel_name, fbuf->channel);
        lcmb->channel_size = strlen (lcmb->channel_name);
        lcmb->data_offset = 0;
        lcmb->data_size = fbuf->data_size;
        lcmb->recv_utime = fbuf->last_packet_utime;

        // don't need the fragment buffer anymore
        lcm_frag_buf_store_remove (lcm->frag_bufs, fbuf);

        return 1;
    }

    return 0;
}
static int
_setup_recv_parts (lcm_udpm_t *lcm)
{
    g_static_rec_mutex_lock(&lcm->mutex);

    // some thread synchronization code to ensure that only one thread sets up the
    // receive thread, and that all threads entering this function after the thread
    // setup begins wait for it to finish.
    if(lcm->creating_read_thread) {
        // check if this thread is the one creating the receive thread.
        // If so, just return.
        if(g_static_private_get(&CREATE_READ_THREAD_PKEY)) {
            g_static_rec_mutex_unlock(&lcm->mutex);
            return 0;
        }

        // ugly bit with two mutexes because we can't use a GStaticRecMutex with a GCond
        g_mutex_lock(lcm->create_read_thread_mutex);
        g_static_rec_mutex_unlock(&lcm->mutex);

        // wait for the thread creating the read thread to finish
        while(lcm->creating_read_thread) {
            g_cond_wait(lcm->create_read_thread_cond, lcm->create_read_thread_mutex);
        }
        g_mutex_unlock(lcm->create_read_thread_mutex);
        g_static_rec_mutex_lock(&lcm->mutex);

        // if we've gotten here, then either the read thread is created, or it
        // was not possible to do so.  Figure out which happened, and return.
        int result = lcm->thread_created ? 0 : -1;
        g_static_rec_mutex_unlock(&lcm->mutex);
        return result;
    } else if(lcm->thread_created) {
        g_static_rec_mutex_unlock(&lcm->mutex);
        return 0;
    }

    // no other thread is trying to create the read thread right now.  claim that task.
    lcm->creating_read_thread = 1;
    lcm->create_read_thread_mutex = g_mutex_new();
    lcm->create_read_thread_cond = g_cond_new();
    // mark this thread as the one creating the read thread
    g_static_private_set(&CREATE_READ_THREAD_PKEY, GINT_TO_POINTER(1), NULL);

    dbg (DBG_LCM, "allocating resources for receiving messages\n");

    // allocate the fragment buffer hashtable
    lcm->frag_bufs = lcm_frag_buf_store_new(MAX_FRAG_BUF_TOTAL_SIZE,
            MAX_NUM_FRAG_BUFS);

    // allocate multicast socket
    lcm->recvfd = socket (AF_INET, SOCK_DGRAM, 0);
    if (lcm->recvfd < 0) {
        perror ("allocating LCM recv socket");
        goto setup_recv_thread_fail;
    }

    struct sockaddr_in addr;
    memset (&addr, 0, sizeof (addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = lcm->params.mc_port;

    // allow other applications on the local machine to also bind to this
    // multicast address and port
    int opt=1;
    dbg (DBG_LCM, "LCM: setting SO_REUSEADDR\n");
    if (setsockopt (lcm->recvfd, SOL_SOCKET, SO_REUSEADDR, 
            (char*)&opt, sizeof (opt)) < 0) {
        perror ("setsockopt (SOL_SOCKET, SO_REUSEADDR)");
        goto setup_recv_thread_fail;
    }

#ifdef USE_REUSEPORT
    /* Mac OS and FreeBSD require the REUSEPORT option in addition
     * to REUSEADDR or it won't let multiple processes bind to the
     * same port, even if they are using multicast. */
    dbg (DBG_LCM, "LCM: setting SO_REUSEPORT\n");
    if (setsockopt (lcm->recvfd, SOL_SOCKET, SO_REUSEPORT, 
            (char*)&opt, sizeof (opt)) < 0) {
        perror ("setsockopt (SOL_SOCKET, SO_REUSEPORT)");
        goto setup_recv_thread_fail;
    }
#endif

#if 0
    // set loopback option so that packets sent out on the multicast socket
    // are also delivered to it
    unsigned char lo_opt = 1;
    dbg (DBG_LCM, "LCM: setting multicast loopback option\n");
    status = setsockopt (lcm->recvfd, IPPROTO_IP, IP_MULTICAST_LOOP, 
            &lo_opt, sizeof (lo_opt));
    if (status < 0) {
        perror ("setting multicast loopback");
        return -1;
    }
#endif

#ifdef WIN32
    // Windows has small (8k) buffer by default
    // Increase it to a default reasonable amount
    int recv_buf_size = 2048 * 1024;
    setsockopt(lcm->recvfd, SOL_SOCKET, SO_RCVBUF, 
            (char*)&recv_buf_size, sizeof(recv_buf_size));
#endif

    // debugging... how big is the receive buffer?
    unsigned int retsize = sizeof (int);
    getsockopt (lcm->recvfd, SOL_SOCKET, SO_RCVBUF, 
            (char*)&lcm->kernel_rbuf_sz, (socklen_t *) &retsize);
    dbg (DBG_LCM, "LCM: receive buffer is %d bytes\n", lcm->kernel_rbuf_sz);
    if (lcm->params.recv_buf_size) {
        if (setsockopt (lcm->recvfd, SOL_SOCKET, SO_RCVBUF,
                (char *) &lcm->params.recv_buf_size, 
                sizeof (lcm->params.recv_buf_size)) < 0) {
            perror ("setsockopt(SOL_SOCKET, SO_RCVBUF)");
            fprintf (stderr, "Warning: Unable to set recv buffer size\n");
        }
        getsockopt (lcm->recvfd, SOL_SOCKET, SO_RCVBUF, 
                (char*)&lcm->kernel_rbuf_sz, (socklen_t *) &retsize);
        dbg (DBG_LCM, "LCM: receive buffer is %d bytes\n", lcm->kernel_rbuf_sz);

        if (lcm->params.recv_buf_size > lcm->kernel_rbuf_sz) {
            g_warning ("LCM UDP receive buffer size (%d) \n"
                    "       is smaller than reqested (%d). "
                    "For more info:\n"
                    "       http://lcm-proj.github.io/multicast_setup.html\n", 
                    lcm->kernel_rbuf_sz, lcm->params.recv_buf_size);
        }
    }

    /* Enable per-packet timestamping by the kernel, if available */
#ifdef SO_TIMESTAMP
    opt = 1;
    setsockopt (lcm->recvfd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof (opt));
#endif

    if (bind (lcm->recvfd, (struct sockaddr*)&addr, sizeof (addr)) < 0) {
        perror ("bind");
        goto setup_recv_thread_fail;
    }

    struct ip_mreq mreq;
    mreq.imr_multiaddr = lcm->params.mc_addr;
    mreq.imr_interface.s_addr = INADDR_ANY;
    // join the multicast group
    dbg (DBG_LCM, "LCM: joining multicast group\n");
    if (setsockopt (lcm->recvfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
            (char*)&mreq, sizeof (mreq)) < 0) {
        perror ("setsockopt (IPPROTO_IP, IP_ADD_MEMBERSHIP)");
        goto setup_recv_thread_fail;
    }

    lcm->inbufs_empty = lcm_buf_queue_new ();
    lcm->inbufs_filled = lcm_buf_queue_new ();
    lcm->ringbuf = lcm_ringbuf_new (LCM_RINGBUF_SIZE);

    int i;
    for (i = 0; i < LCM_DEFAULT_RECV_BUFS; i++) {
        /* We don't set the receive buffer's data pointer yet because it
         * will be taken from the ringbuffer at receive time. */
        lcm_buf_t * lcmb = (lcm_buf_t *) calloc (1, sizeof (lcm_buf_t));
        lcm_buf_enqueue (lcm->inbufs_empty, lcmb);
    }

    // setup a pipe for notifying the reader thread when to quit
    if(0 != lcm_internal_pipe_create(lcm->thread_msg_pipe)) {
        perror(__FILE__ " pipe(setup)");
        goto setup_recv_thread_fail;
    }
    fcntl (lcm->thread_msg_pipe[1], F_SETFL, O_NONBLOCK);

    /* Start the reader thread */
    lcm->read_thread = g_thread_create (recv_thread, lcm, TRUE, NULL);
    if (!lcm->read_thread) {
        fprintf (stderr, "Error: LCM failed to start reader thread\n");
        goto setup_recv_thread_fail;
    }
    lcm->thread_created = 1;
    g_static_rec_mutex_unlock(&lcm->mutex);

    // conduct a self-test just to make sure everything is working.
    dbg (DBG_LCM, "LCM: conducting self test\n");
    int self_test_results = udpm_self_test(lcm);
    g_static_rec_mutex_lock(&lcm->mutex);

    if (0 == self_test_results) {
        dbg (DBG_LCM, "LCM: self test successful\n");
    } else {
        // self test failed.  destroy the read thread
        fprintf (stderr, "LCM self test failed!!\n"
                "Check your routing tables and firewall settings\n");
        _destroy_recv_parts (lcm);
    }

    // notify threads waiting for the read thread to be created
    g_mutex_lock(lcm->create_read_thread_mutex);
    lcm->creating_read_thread = 0;
    g_cond_broadcast(lcm->create_read_thread_cond);
    g_mutex_unlock(lcm->create_read_thread_mutex);
    g_static_rec_mutex_unlock(&lcm->mutex);

    return self_test_results;

setup_recv_thread_fail:
    _destroy_recv_parts (lcm);
    g_static_rec_mutex_unlock(&lcm->mutex);
    return -1;
}
Exemple #8
0
/**
 * z_dispatch_chain_unlock:
 * @self this
 *
 * Unlock the chain's mutex
 */
static inline void
z_dispatch_chain_unlock(ZDispatchChain *self)
{
  g_static_rec_mutex_unlock(&self->lock);
}
/**
 * e_intervaltree_insert:
 * @tree: interval tree
 * @start: start of the interval
 * @end: end of the interval
 * @comp: Component
 * 
 * Since: 2.32
 **/
gboolean
e_intervaltree_insert (EIntervalTree *tree,
                       time_t start,
                       time_t end,
                       ECalComponent *comp)
{
	EIntervalTreePrivate *priv;
	EIntervalNode *y;
	EIntervalNode *x;
	EIntervalNode *newNode;
	const gchar *uid;
	gchar *rid;

	g_return_val_if_fail (tree != NULL, FALSE);
	g_return_val_if_fail (comp != NULL, FALSE);
	g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);

	priv = tree->priv;

	g_static_rec_mutex_lock (&priv->mutex);

	e_cal_component_get_uid (comp, &uid);
	rid = e_cal_component_get_recurid_as_string (comp);
	e_intervaltree_remove (tree, uid, rid);

	x = g_new (EIntervalNode, 1);
	x->min = x->start = start;
	x->max = x->end = end;
	x->comp = g_object_ref (comp);

	binary_tree_insert (tree, x);
	newNode = x;
	x->red = TRUE;

	fixup_min_max_fields (tree, x->parent);
	while (x->parent->red)
	{ /* use sentinel instead of checking for root */
		if (x->parent == x->parent->parent->left)
		{
			y = x->parent->parent->right;

			if (y->red)
			{
				x->parent->red = FALSE;
				y->red = FALSE;
				x->parent->parent->red = TRUE;
				x = x->parent->parent;
			}
			else
			{
				if (x == x->parent->right)
				{
					x = x ->parent;
					left_rotate (tree, x);
				}

				x->parent->red = FALSE;
				x->parent->parent->red = TRUE;
				right_rotate (tree, x->parent->parent);
			}
		}
		else
		{ /* case for x->parent == x->parent->parent->right */
			y = x->parent->parent->left;

			if (y->red)
			{
				x->parent->red = FALSE;
				y->red = FALSE;
				x->parent->parent->red = TRUE;
				x = x->parent->parent;
			}
			else
			{
				if (x == x->parent->left)
				{
					x = x->parent;
					right_rotate (tree, x);
				}

				x->parent->red = FALSE;
				x->parent->parent->red = TRUE;
				left_rotate (tree, x->parent->parent);
			}
		}
	}

	priv->root->left->red = FALSE;
	g_hash_table_insert (priv->id_node_hash, component_key (uid, rid), newNode);
	g_free (rid);

	g_static_rec_mutex_unlock (&priv->mutex);

	return TRUE;
}
static void
gst_vader_set_property(GObject * object, guint prop_id,
                       const GValue * value, GParamSpec * pspec)
{
    GstVader *filter;

    g_return_if_fail(GST_IS_VADER(object));
    filter = GST_VADER(object);

    switch (prop_id) {
    case PROP_THRESHOLD:
        filter->threshold_level = (gint)(g_value_get_double(value) * 32768.0);
        break;
    case PROP_AUTO_THRESHOLD:
        /* We are going to muck around with things... */
        g_static_rec_mutex_lock(&filter->mtx);
        filter->auto_threshold = g_value_get_boolean(value);
        /* Setting this to TRUE re-initializes auto calibration. */
        if (filter->auto_threshold) {
            /* We have to be in silence mode to calibrate. */
            filter->silent_prev = filter->silent;
            filter->silent = TRUE;
            /* Do "artifical" sil-speech or speech-sil transitions. */
            if (filter->silent != filter->silent_prev) {
                gst_vader_transition(filter, gst_clock_get_time(GST_ELEMENT_CLOCK(filter)));
            }
            /* Reset counters and such. */
            filter->threshold_level = -1;
            memset(filter->window, 0, sizeof(*filter->window) * VADER_WINDOW);
            filter->silence_mean = 0;
            filter->silence_stddev = 0;
            filter->silence_frames = 0;
        }
        g_static_rec_mutex_unlock(&filter->mtx);
        break;
    case PROP_SILENT:
        /* We are going to muck around with things... */
        g_static_rec_mutex_lock(&filter->mtx);
        filter->silent_prev = filter->silent;
        filter->silent = g_value_get_boolean(value);
        /* Do "artifical" sil-speech or speech-sil transitions. */
        if (filter->silent != filter->silent_prev) {
            gst_vader_transition(filter, gst_clock_get_time(GST_ELEMENT_CLOCK(filter)));
            /* Also flush the voting window so we don't go right back into speech. */
            memset(filter->window, 0, sizeof(*filter->window) * VADER_WINDOW);
        }
        g_static_rec_mutex_unlock(&filter->mtx);
        break;
    case PROP_RUN_LENGTH:
        filter->threshold_length = g_value_get_uint64(value);
        break;
    case PROP_PRE_LENGTH:
        filter->pre_length = g_value_get_uint64(value);
        break;
    case PROP_DUMPDIR:
        g_free(filter->dumpdir);
        filter->dumpdir = g_strdup(g_value_get_string(value));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
        break;
    }
}
Exemple #11
0
static void
package_lock_leave (void)
{
  g_static_rec_mutex_unlock (&package_mutex);
}
static GstFlowReturn
gst_vader_chain(GstPad * pad, GstBuffer * buf)
{
    GstVader *filter;
    gint16 *in_data;
    guint num_samples;
    gint i, vote;
    guint power, rms;

    g_return_val_if_fail(pad != NULL, GST_FLOW_ERROR);
    g_return_val_if_fail(GST_IS_PAD(pad), GST_FLOW_ERROR);
    g_return_val_if_fail(buf != NULL, GST_FLOW_ERROR);

    filter = GST_VADER(GST_OBJECT_PARENT(pad));
    g_return_val_if_fail(filter != NULL, GST_FLOW_ERROR);
    g_return_val_if_fail(GST_IS_VADER(filter), GST_FLOW_ERROR);

    in_data = (gint16 *) GST_BUFFER_DATA(buf);
    num_samples = GST_BUFFER_SIZE(buf) / 2;

    /* Enter a critical section. */
    g_static_rec_mutex_lock(&filter->mtx);
    filter->silent_prev = filter->silent;
    /* If we are in auto-threshold mode, check to see if we have
     * enough data to estimate a threshold.  (FIXME: we should be
     * estimating at the sample level rather than the frame level,
     * probably) */
    if (filter->threshold_level == -1) {
        if (filter->silence_frames > 5) {
            filter->silence_mean /= filter->silence_frames;
            filter->silence_stddev /= filter->silence_frames;
            filter->silence_stddev -= filter->silence_mean * filter->silence_mean;
            filter->silence_stddev = fixpoint_bogus_sqrt(filter->silence_stddev);
            /* Set threshold three standard deviations from the mean. */
            filter->threshold_level = filter->silence_mean + 3 * filter->silence_stddev;
            GST_DEBUG_OBJECT(filter, "silence_mean %d stddev %d auto_threshold %d\n",
                             filter->silence_mean, filter->silence_stddev,
                             filter->threshold_level);
        }
    }

    /* Divide buffer into reasonably sized parts. */
    for (i = 0; i < num_samples; i += VADER_FRAME) {
        gint frame_len, j;

        frame_len = MIN(num_samples - i, VADER_FRAME);
        power = compute_normed_power(in_data + i, frame_len, &filter->prior_sample);
        rms = fixpoint_sqrt_q15(power);

        /* If we are in auto-threshold mode, don't do any voting etc. */
        if (filter->threshold_level == -1) {
            filter->silence_mean += rms;
            filter->silence_stddev += rms * rms;
            filter->silence_frames += 1;
            GST_DEBUG_OBJECT(filter, "silence_mean_acc %d silence_stddev_acc %d frames %d\n",
                             filter->silence_mean, filter->silence_stddev, filter->silence_frames);
            continue;
        }
        /* Shift back window values. */
        memmove(filter->window, filter->window + 1,
                (VADER_WINDOW - 1) * sizeof(*filter->window));

        /* Decide if this buffer is silence or not. */
        if (rms > filter->threshold_level)
            filter->window[VADER_WINDOW-1] = TRUE;
        else
            filter->window[VADER_WINDOW-1] = FALSE;

        /* Vote on whether we have entered a region of non-silence. */
        vote = 0;
        for (j = 0; j < VADER_WINDOW; ++j)
            vote += filter->window[j];

        GST_DEBUG_OBJECT(filter, "frame_len %d rms power %d threshold %d vote %d\n",
                         frame_len, rms, filter->threshold_level, vote);

        if (vote > VADER_WINDOW / 2) {
            filter->silent_run_length = 0;
            filter->silent = FALSE;
        }
        else {
            filter->silent_run_length
                += gst_audio_duration_from_pad_buffer(filter->sinkpad, buf);
        }

        if (filter->silent_run_length > filter->threshold_length)
            /* it has been silent long enough, flag it */
            filter->silent = TRUE;
    }

    /* Handle transitions between silence and non-silence. */
    if (filter->silent != filter->silent_prev) {
        gst_vader_transition(filter, GST_BUFFER_TIMESTAMP(buf));
    }
    /* Handling of silence detection is done. */
    g_static_rec_mutex_unlock(&filter->mtx);

    /* now check if we have to send the new buffer to the internal buffer cache
     * or to the srcpad */
    if (filter->silent) {
        /* Claim the lock while manipulating the queue. */
        g_static_rec_mutex_lock(&filter->mtx);
        filter->pre_buffer = g_list_append(filter->pre_buffer, buf);
        filter->pre_run_length +=
            gst_audio_duration_from_pad_buffer(filter->sinkpad, buf);
        while (filter->pre_run_length > filter->pre_length) {
            GstBuffer *prebuf;

            prebuf = (g_list_first(filter->pre_buffer))->data;
            g_assert(GST_IS_BUFFER(prebuf));
            filter->pre_buffer = g_list_remove(filter->pre_buffer, prebuf);
            filter->pre_run_length -=
                gst_audio_duration_from_pad_buffer(filter->sinkpad, prebuf);
            gst_buffer_unref(prebuf);
        }
        g_static_rec_mutex_unlock(&filter->mtx);
    } else {
        if (filter->dumpfile)
            fwrite(GST_BUFFER_DATA(buf), 1, GST_BUFFER_SIZE(buf),
                   filter->dumpfile);
        gst_pad_push(filter->srcpad, buf);
    }

    return GST_FLOW_OK;
}
static void
gst_vader_transition(GstVader *filter, GstClockTime ts)
{
    /* NOTE: This function MUST be called with filter->mtx held! */
    /* has the silent status changed ? if so, send right signal
     * and, if from silent -> not silent, flush pre_record buffer
     */
    if (filter->silent) {
        /* Sound to silence transition. */
        GstMessage *m =
            gst_vader_message_new(filter, FALSE, ts);
        GstEvent *e =
            gst_vader_event_new(filter, GST_EVENT_VADER_STOP, ts);
        GST_DEBUG_OBJECT(filter, "signaling CUT_STOP");
        gst_element_post_message(GST_ELEMENT(filter), m);
        /* Insert a custom event in the stream to mark the end of a cut. */
        /* This will block if the pipeline is paused so we have to unlock. */
        g_static_rec_mutex_unlock(&filter->mtx);
        gst_pad_push_event(filter->srcpad, e);
        g_static_rec_mutex_lock(&filter->mtx);
        /* FIXME: That event's timestamp is wrong... as is this one. */
        g_signal_emit(filter, gst_vader_signals[SIGNAL_VADER_STOP], 0, ts);
        /* Stop dumping audio */
        if (filter->dumpfile) {
            fclose(filter->dumpfile);
            filter->dumpfile = NULL;
            ++filter->dumpidx;
        }
    } else {
        /* Silence to sound transition. */
        gint count = 0;
        GstMessage *m;
        GstEvent *e;

        GST_DEBUG_OBJECT(filter, "signaling CUT_START");
        /* Use the first pre_buffer's timestamp for the signal if possible. */
        if (filter->pre_buffer) {
            GstBuffer *prebuf;

            prebuf = (g_list_first(filter->pre_buffer))->data;
            ts = GST_BUFFER_TIMESTAMP(prebuf);
        }

        g_signal_emit(filter, gst_vader_signals[SIGNAL_VADER_START],
                      0, ts);
        m = gst_vader_message_new(filter, TRUE, ts);
        e = gst_vader_event_new(filter, GST_EVENT_VADER_START, ts);
        gst_element_post_message(GST_ELEMENT(filter), m);

        /* Insert a custom event in the stream to mark the beginning of a cut. */
        /* This will block if the pipeline is paused so we have to unlock. */
        g_static_rec_mutex_unlock(&filter->mtx);
        gst_pad_push_event(filter->srcpad, e);
        g_static_rec_mutex_lock(&filter->mtx);

        /* Start dumping audio */
        if (filter->dumpdir) {
            gchar *filename = g_strdup_printf("%s/%08d.raw", filter->dumpdir,
                                              filter->dumpidx);
            filter->dumpfile = fopen(filename, "wb");
            g_free(filename);
        }

        /* first of all, flush current buffer */
        GST_DEBUG_OBJECT(filter, "flushing buffer of length %" GST_TIME_FORMAT,
                         GST_TIME_ARGS(filter->pre_run_length));
        while (filter->pre_buffer) {
            GstBuffer *prebuf;

            prebuf = (g_list_first(filter->pre_buffer))->data;
            filter->pre_buffer = g_list_remove(filter->pre_buffer, prebuf);
            if (filter->dumpfile)
                fwrite(GST_BUFFER_DATA(prebuf), 1, GST_BUFFER_SIZE(prebuf),
                       filter->dumpfile);
            /* This will block if the pipeline is paused so we have to unlock. */
            g_static_rec_mutex_unlock(&filter->mtx);
            gst_pad_push(filter->srcpad, prebuf);
            g_static_rec_mutex_lock(&filter->mtx);
            ++count;
        }
        GST_DEBUG_OBJECT(filter, "flushed %d buffers", count);
        filter->pre_run_length = 0;
    }
}
Exemple #14
0
static IrisReceiveDecision
can_receive (IrisArbiter  *arbiter,
             IrisReceiver *receiver)
{
	IrisCoordinationArbiter        *coord;
	IrisCoordinationArbiterPrivate *priv;
	IrisReceiver                   *resume   = NULL;
	IrisReceiveDecision             decision = IRIS_RECEIVE_NEVER;

	g_return_val_if_fail (IRIS_IS_COORDINATION_ARBITER (arbiter), IRIS_RECEIVE_NEVER);
	g_return_val_if_fail (IRIS_IS_RECEIVER (receiver), IRIS_RECEIVE_NEVER);

	coord = IRIS_COORDINATION_ARBITER (arbiter);
	priv = coord->priv;

	g_static_rec_mutex_lock (&priv->mutex);

	/* Current Receiver: ANY
	 * Request Receiver: ANY
	 * Has Active......: ANY
	 * Pending.........: ANY
	 * Completed.......: YES
	 * Receive.........: NEVER
	 */
	if (priv->flags & IRIS_COORD_COMPLETE) {
		decision = IRIS_RECEIVE_NEVER;
		goto finish;
	}

	/* Current Receiver: TEARDOWN
	 * Request Receiver: CONCURRENT or EXCLUSIVE
	 * Has Active......: ANY
	 * Pending.........: ANY
	 * Receive.........: NEVER
	 */
	if (priv->flags & IRIS_COORD_TEARDOWN) {
		if (receiver == priv->concurrent || receiver == priv->exclusive) {
			decision = IRIS_RECEIVE_NEVER;
			goto finish;
		}
	}

	/* Current Receiver: TEARDOWN
	 * Request Receiver: TEARDOWN
	 * Has Active......: 0
	 * Pending.........: NONE
	 * Completed.......: NO
	 * Receive.........: NOW
	 */
	if (priv->flags & IRIS_COORD_TEARDOWN) {
		if ((priv->flags & IRIS_COORD_COMPLETE) == 0) {
			if (receiver == priv->teardown) {
				if (priv->active == 0) {
					decision = IRIS_RECEIVE_NOW;
					priv->flags &= ~IRIS_COORD_NEEDS_TEARDOWN;
					priv->flags |= IRIS_COORD_COMPLETE;
					goto finish;
				}
			}
		}
	}

	/* Current Receiver: TEARDOWN
	 * Request Receiver: TEARDOWN
	 * Has Active......: YES
	 * Pending.........: NONE
	 * Completed.......: NO
	 * Receive.........: NEVER
	 */
	if (priv->flags & IRIS_COORD_TEARDOWN) {
		if (receiver == priv->teardown) {
			if (priv->active > 0) {
				if ((priv->flags & IRIS_COORD_COMPLETE) == 0) {
					decision = IRIS_RECEIVE_NEVER;
					goto finish;
				}
			}
		}
	}

	/* Current Receiver: ANY
	 * Request Receiver: CONCURRENT or EXCUSIVE
	 * Has Active......: ANY
	 * Pending.........: TEARDOWN
	 * Receive.........: NEVER
	 */
	if (receiver == priv->concurrent || receiver == priv->exclusive) {
		if (priv->flags & IRIS_COORD_NEEDS_TEARDOWN) {
			decision = IRIS_RECEIVE_NEVER;
			goto finish;
		}
	}

	/* Current Receiver: CONCURRENT
	 * Request Receiver: CONCURRENT
	 * Has Active......: *
	 * Pending.........: NONE or CONCURRENT
	 * Receive.........: NOW
	 */
	if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
		if (receiver == priv->concurrent) {
			if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_CONCURRENT) == IRIS_COORD_NEEDS_CONCURRENT) {
				decision = IRIS_RECEIVE_NOW;
				priv->flags &= ~IRIS_COORD_NEEDS_CONCURRENT;
				resume = priv->concurrent;
				goto finish;
			}
		}
	}

	/* Current Receiver: CONCURRENT
	 * Request Receiver: CONCURRENT
	 * Has Active......: *
	 * Pending.........: ANY
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
		if (receiver == priv->concurrent) {
			if ((priv->flags & IRIS_COORD_NEEDS_ANY) != 0) {
				decision = IRIS_RECEIVE_LATER;
				priv->flags |= IRIS_COORD_NEEDS_CONCURRENT;
				goto finish;
			}
		}
	}

	/* Current Receiver: CONCURRENT
	 * Request Receiver: EXCLUSIVE
	 * Has Active......: YES
	 * Pending.........: ANY
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
		if (receiver == priv->exclusive) {
			if (priv->active > 0) {
				decision = IRIS_RECEIVE_LATER;
				priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE;
				goto finish;
			}
		}
	}

	/* Current Receiver: CONCURRENT
	 * Request Receiver: EXCLUSIVE
	 * Has Active......: NO
	 * Pending.........: NONE or EXCLUSIVE
	 * Receive.........: NOW
	 */
	if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
		if (receiver == priv->exclusive) {
			if (priv->active == 0) {
				if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_EXCLUSIVE) == IRIS_COORD_NEEDS_EXCLUSIVE) {
					decision = IRIS_RECEIVE_NOW;
					priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_EXCLUSIVE);
					priv->flags |= IRIS_COORD_EXCLUSIVE;
					goto finish;
				}
			}
		}
	}

	/* Current Receiver: CONCURRENT
	 * Request Receiver: EXCLUSIVE
	 * Has Active......: NO
	 * Pending.........: EXCLUSIVE or TEARDOWN
	 * Receive.........: NOW
	 */
	if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
		if (receiver == priv->exclusive) {
			if (priv->active == 0) {
				if ((priv->flags & IRIS_COORD_NEEDS_ANY) != IRIS_COORD_NEEDS_CONCURRENT) {
					decision = IRIS_RECEIVE_NOW;
					priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_EXCLUSIVE);
					priv->flags |= IRIS_COORD_EXCLUSIVE;
					goto finish;
				}
			}
		}
	}

	/* Current Receiver: CONCURRENT
	 * Request Receiver: TEARDOWN
	 * Has Active......: NO
	 * Pending.........: NONE or TEARDOWN
	 * Receive.........: NOW
	 */
	if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
		if (receiver == priv->teardown) {
			if (priv->active == 0) {
				if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_TEARDOWN) == IRIS_COORD_NEEDS_TEARDOWN) {
					decision = IRIS_RECEIVE_NOW;
					priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_TEARDOWN);
					priv->flags |= IRIS_COORD_TEARDOWN;
					goto finish;
				}
			}
		}
	}

	/* Current Receiver: CONCURRENT
	 * Request Receiver: TEARDOWN
	 * Has Active......: YES
	 * Pending.........: ANY
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
		if (receiver == priv->teardown) {
			if (priv->active > 0) {
				decision = IRIS_RECEIVE_LATER;
				priv->flags |= IRIS_COORD_NEEDS_TEARDOWN;
				goto finish;
			}
		}
	}

	/* Current Receiver: CONCURRENT
	 * Request Receiver: TEARDOWN
	 * Has Active......: NO
	 * Pending.........: ANY
	 * Receive.........: NOW
	 */
	if ((priv->flags & IRIS_COORD_CONCURRENT) != 0) {
		if (receiver == priv->teardown) {
			if (priv->active == 0) {
				decision = IRIS_RECEIVE_NOW;
				priv->flags &= ~(IRIS_COORD_CONCURRENT | IRIS_COORD_NEEDS_TEARDOWN);
				priv->flags |= IRIS_COORD_TEARDOWN;
				goto finish;
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: EXCLUSIVE
	 * Has Active......: YES
	 * Pending.........: ANY
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->exclusive) {
			if (priv->active > 0) {
				decision = IRIS_RECEIVE_LATER;
				priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE;
				goto finish;
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: EXCLUSIVE
	 * Has Active......: NO
	 * Pending.........: ANY
	 * Receive.........: NOW
	 * Notes...........: This should help us utilize our exclusive mode
	 *                   better so we don't do so many switches when
	 *                   already in exclusive mode.
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->exclusive) {
			if (priv->active == 0) {
				decision = IRIS_RECEIVE_NOW;
				priv->flags &= ~IRIS_COORD_NEEDS_EXCLUSIVE;
				goto finish;
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: EXCLUSIVE
	 * Has Active......: NO
	 * Pending.........: CONCURRENT or TEARDOWN
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->exclusive) {
			if (priv->active == 0) {
				if ((priv->flags & IRIS_COORD_NEEDS_ANY) & ~IRIS_COORD_NEEDS_EXCLUSIVE) {
					decision = IRIS_RECEIVE_LATER;
					priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE;
					goto finish;
				}
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: EXCLUSIVE
	 * Has Active......: YES
	 * Pending.........: ANY
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->exclusive) {
			if (priv->active > 0) {
				decision = IRIS_RECEIVE_LATER;
				priv->flags |= IRIS_COORD_NEEDS_EXCLUSIVE;
				goto finish;
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: CONCURRENT
	 * Has Active......: NO
	 * Pending.........: NONE or CONCURRENT
	 * Receive.........: NOW
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->concurrent) {
			if (priv->active == 0) {
				if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_CONCURRENT) == IRIS_COORD_NEEDS_CONCURRENT) {
					decision = IRIS_RECEIVE_NOW;
					priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_CONCURRENT);
					priv->flags |= IRIS_COORD_CONCURRENT;
					resume = priv->concurrent;
					goto finish;
				}
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: CONCURRENT
	 * Has Active......: NO
	 * Pending.........: EXCLUSIVE or TEARDOWN
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->concurrent) {
			if (priv->active == 0) {
				if ((priv->flags & IRIS_COORD_NEEDS_ANY) & ~IRIS_COORD_NEEDS_CONCURRENT) {
					decision = IRIS_RECEIVE_LATER;
					priv->flags |= IRIS_COORD_NEEDS_CONCURRENT;
					goto finish;
				}
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: CONCURRENT
	 * Has Active......: YES
	 * Pending.........: ANY
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->concurrent) {
			if (priv->active > 0) {
				decision = IRIS_RECEIVE_LATER;
				priv->flags |= IRIS_COORD_NEEDS_CONCURRENT;
				goto finish;
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: TEARDOWN
	 * Has Active......: NO
	 * Pending.........: NONE or TEARDOWN
	 * Receive.........: NOW
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->teardown) {
			if (priv->active == 0) {
				if (((priv->flags & IRIS_COORD_NEEDS_ANY) | IRIS_COORD_NEEDS_TEARDOWN) == IRIS_COORD_NEEDS_TEARDOWN) {
					decision = IRIS_RECEIVE_NOW;
					priv->flags &= ~(IRIS_COORD_EXCLUSIVE | IRIS_COORD_NEEDS_TEARDOWN);
					priv->flags |= IRIS_COORD_TEARDOWN;
					goto finish;
				}
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: TEARDOWN
	 * Has Active......: YES
	 * Pending.........: ANY
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->teardown) {
			if (priv->active > 0) {
				decision = IRIS_RECEIVE_LATER;
				priv->flags |= IRIS_COORD_NEEDS_TEARDOWN;
				goto finish;
			}
		}
	}

	/* Current Receiver: EXCLUSIVE
	 * Request Receiver: TEARDOWN
	 * Has Active......: NO
	 * Pending.........: ANY
	 * Receive.........: LATER
	 */
	if ((priv->flags & IRIS_COORD_EXCLUSIVE) != 0) {
		if (receiver == priv->teardown) {
			if (priv->active <= 0) {
				decision = IRIS_RECEIVE_LATER;
				priv->flags |= IRIS_COORD_NEEDS_TEARDOWN;
				goto finish;
			}
		}
	}

	g_print ("\nMISSING ARBITER BRANCH REPORT\n"
		 "====================================\n"
		 "Current.....: %s\n"
		 "Receiver....: %s\n"
		 "Active......: %lu\n"
		 "Pending.....: %u\n",
		 (priv->flags & IRIS_COORD_EXCLUSIVE) ? "EXCLUSIVE" : (priv->flags & IRIS_COORD_CONCURRENT) ? "CONCURRENT" : "TEARDOWN",
		 (receiver == priv->exclusive)        ? "EXCLUSIVE" : (receiver == priv->concurrent)        ? "CONCURRENT" : "TEARDOWN",
		 priv->active,
		 priv->flags & IRIS_COORD_NEEDS_ANY);

finish:
	if (decision == IRIS_RECEIVE_NOW) {
		if (receiver == priv->teardown)
			priv->flags |= IRIS_COORD_COMPLETE;
		g_atomic_int_inc ((gint*)&priv->active);
	}

	/* It would be nice to hold on to this lock while we resume to make
	 * sure our resuming receiver gets more in, but it can create a
	 * dead-lock if we are calling resume and try to lock on the receiver
	 * while someone in the receiver thread is trying to lock on us to
	 * try to deliver. */
	g_static_rec_mutex_unlock (&priv->mutex);

	if (resume)
		iris_receiver_resume (resume);

	return decision;
}
Exemple #15
0
GModule*
g_module_open (const gchar    *file_name,
	       GModuleFlags    flags)
{
  GModule *module;
  gpointer handle = NULL;
  gchar *name = NULL;
  
  SUPPORT_OR_RETURN (NULL);
  
  g_static_rec_mutex_lock (&g_module_global_lock);

  if (G_UNLIKELY (!module_debug_initialized))
    _g_module_debug_init ();

  if (module_debug_flags & G_MODULE_DEBUG_BIND_NOW_MODULES)
    flags &= ~G_MODULE_BIND_LAZY;

  if (!file_name)
    {      
      if (!main_module)
	{
	  handle = _g_module_self ();
	  if (handle)
	    {
	      main_module = g_new (GModule, 1);
	      main_module->file_name = NULL;
#if defined (G_OS_WIN32) && !defined(_WIN64)
	      main_module->cp_file_name = NULL;
#endif
	      main_module->handle = handle;
	      main_module->ref_count = 1;
	      main_module->is_resident = TRUE;
	      main_module->unload = NULL;
	      main_module->next = NULL;
	    }
	}
      else
	main_module->ref_count++;

      g_static_rec_mutex_unlock (&g_module_global_lock);
      return main_module;
    }
  
  /* we first search the module list by name */
  module = g_module_find_by_name (file_name);
  if (module)
    {
      module->ref_count++;
      
      g_static_rec_mutex_unlock (&g_module_global_lock);
      return module;
    }

  /* check whether we have a readable file right away */
  if (g_file_test (file_name, G_FILE_TEST_IS_REGULAR))
    name = g_strdup (file_name);
  /* try completing file name with standard library suffix */
  if (!name)
    {
      name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL);
      if (!g_file_test (name, G_FILE_TEST_IS_REGULAR))
	{
	  g_free (name);
	  name = NULL;
	}
    }
  /* try completing by appending libtool suffix */
  if (!name)
    {
      name = g_strconcat (file_name, ".la", NULL);
      if (!g_file_test (name, G_FILE_TEST_IS_REGULAR))
	{
	  g_free (name);
	  name = NULL;
	}
    }
  /* we can't access() the file, lets hope the platform backends finds
   * it via library paths
   */
  if (!name)
    {
      gchar *dot = strrchr (file_name, '.');
      gchar *slash = strrchr (file_name, G_DIR_SEPARATOR);
      
      /* make sure the name has a suffix */
      if (!dot || dot < slash)
	name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL);
      else
	name = g_strdup (file_name);
    }

  /* ok, try loading the module */
  if (name)
    {
      /* if it's a libtool archive, figure library file to load */
      if (str_check_suffix (name, ".la")) /* libtool archive? */
	{
	  gchar *real_name = parse_libtool_archive (name);

	  /* real_name might be NULL, but then module error is already set */
	  if (real_name)
	    {
	      g_free (name);
	      name = real_name;
            }
	}
      if (name)
	handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0,
			(flags & G_MODULE_BIND_LOCAL) != 0);
    }
  else
    {
      gchar *display_file_name = g_filename_display_name (file_name);
      g_module_set_error_unduped (g_strdup_printf ("unable to access file \"%s\"", display_file_name));
      g_free (display_file_name);
    }
  g_free (name);

  if (handle)
    {
      gchar *saved_error;
      GModuleCheckInit check_init;
      const gchar *check_failed = NULL;
      
      /* search the module list by handle, since file names are not unique */
      module = g_module_find_by_handle (handle);
      if (module)
	{
	  _g_module_close (module->handle, TRUE);
	  module->ref_count++;
	  g_module_set_error (NULL);
	  
	  g_static_rec_mutex_unlock (&g_module_global_lock);
	  return module;
	}
      
      saved_error = g_strdup (g_module_error ());
      g_module_set_error (NULL);
      
      module = g_new (GModule, 1);
      module->file_name = g_strdup (file_name);
#if defined (G_OS_WIN32) && !defined(_WIN64)
      module->cp_file_name = g_locale_from_utf8 (file_name, -1,
						 NULL, NULL, NULL);
#endif
      module->handle = handle;
      module->ref_count = 1;
      module->is_resident = FALSE;
      module->unload = NULL;
      module->next = modules;
      modules = module;
      
      /* check initialization */
      if (g_module_symbol (module, "g_module_check_init", (gpointer) &check_init) && check_init != NULL)
	check_failed = check_init (module);
      
      /* we don't call unload() if the initialization check failed. */
      if (!check_failed)
	g_module_symbol (module, "g_module_unload", (gpointer) &module->unload);
      
      if (check_failed)
	{
	  gchar *error;

	  error = g_strconcat ("GModule (", file_name, ") ",
                               "initialization check failed: ",
                               check_failed, NULL);
	  g_module_close (module);
	  module = NULL;
	  g_module_set_error (error);
	  g_free (error);
	}
      else
	g_module_set_error (saved_error);

      g_free (saved_error);
    }

  if (module != NULL &&
      (module_debug_flags & G_MODULE_DEBUG_RESIDENT_MODULES))
    g_module_make_resident (module);

  g_static_rec_mutex_unlock (&g_module_global_lock);
  return module;
}
/**
 * e_intervaltree_remove:
 * @tree: an #EIntervalTree
 *
 * Since: 2.32
 **/
gboolean
e_intervaltree_remove (EIntervalTree *tree,
                       const gchar *uid,
                       const gchar *rid)
{
	EIntervalTreePrivate *priv;
	EIntervalNode *y;
	EIntervalNode *x;
	EIntervalNode *z;
	EIntervalNode *nil, *root;
	gchar *key;

	g_return_val_if_fail (tree != NULL, FALSE);

	priv = tree->priv;
	nil = priv->nil;
	root = priv->root;
	g_static_rec_mutex_lock (&priv->mutex);

	z = e_intervaltree_search_component (tree, uid, rid);

	if (!z || z == nil) {
		g_static_rec_mutex_unlock (&priv->mutex);
		return FALSE;
	}

	y = ((z->left == nil) || (z->right == nil)) ? z : intervaltree_node_next (tree, z);
	x = (y->left == nil) ? y->right : y->left;
	/* y is to be spliced out. x is it's only child */

	x->parent = y->parent;

	if (root == x->parent)
		root->left = x;
	else
	{
		if (y == y->parent->left)
			y->parent->left = x;
		else
			y->parent->right = x;
	}

	if (y != z)
	{
		/* y (the succesor of z) is the node to be spliced out */
		g_return_val_if_fail (y != priv->nil, FALSE);

		y->max = _TIME_MIN;
		y->min = _TIME_MAX;
		y->left = z->left;
		y->right = z->right;
		y->parent = z->parent;
		z->left->parent = z->right->parent = y;

		if (z == z->parent->left)
			z->parent->left = y;
		else
			z->parent->right = y;

		fixup_min_max_fields (tree, x->parent);

		if (!(y->red))
		{
			y->red = z->red;
			e_intervaltree_fixup_deletion (tree, x);
		}
		else
			y->red = z->red;
	}
	else
	{
		/* z is the node to be spliced out */

		fixup_min_max_fields (tree, x->parent);

		if (!(y->red))
			e_intervaltree_fixup_deletion (tree, x);
	}

	key = component_key (uid, rid);
	g_hash_table_remove (priv->id_node_hash, key);
	g_free (key);

	g_object_unref (z->comp);
	g_free (z);
	g_static_rec_mutex_unlock (&priv->mutex);

	return TRUE;
}
Exemple #17
0
static void
gst_task_func (GstTask * task)
{
  GStaticRecMutex *lock;
  GThread *tself;
  GstTaskPrivate *priv;

  priv = task->priv;

  tself = g_thread_self ();

  GST_DEBUG ("Entering task %p, thread %p", task, tself);

  /* we have to grab the lock to get the mutex. We also
   * mark our state running so that nobody can mess with
   * the mutex. */
  GST_OBJECT_LOCK (task);
  if (task->state == GST_TASK_STOPPED)
    goto exit;
  lock = GST_TASK_GET_LOCK (task);
  if (G_UNLIKELY (lock == NULL))
    goto no_lock;
  task->abidata.ABI.thread = tself;
  /* only update the priority when it was changed */
  if (priv->prio_set)
    g_thread_set_priority (tself, priv->priority);
  GST_OBJECT_UNLOCK (task);

  /* fire the enter_thread callback when we need to */
  if (priv->thr_callbacks.enter_thread)
    priv->thr_callbacks.enter_thread (task, tself, priv->thr_user_data);

  /* locking order is TASK_LOCK, LOCK */
  g_static_rec_mutex_lock (lock);
  GST_OBJECT_LOCK (task);
  /* configure the thread name now */
  gst_task_configure_name (task);

  while (G_LIKELY (task->state != GST_TASK_STOPPED)) {
    while (G_UNLIKELY (task->state == GST_TASK_PAUSED)) {
      gint t;

      t = g_static_rec_mutex_unlock_full (lock);
      if (t <= 0) {
        g_warning ("wrong STREAM_LOCK count %d", t);
      }
      GST_TASK_SIGNAL (task);
      GST_TASK_WAIT (task);
      GST_OBJECT_UNLOCK (task);
      /* locking order.. */
      if (t > 0)
        g_static_rec_mutex_lock_full (lock, t);

      GST_OBJECT_LOCK (task);
      if (G_UNLIKELY (task->state == GST_TASK_STOPPED))
        goto done;
    }
    GST_OBJECT_UNLOCK (task);

    task->func (task->data);

    GST_OBJECT_LOCK (task);
  }
done:
  GST_OBJECT_UNLOCK (task);
  g_static_rec_mutex_unlock (lock);

  GST_OBJECT_LOCK (task);
  task->abidata.ABI.thread = NULL;

exit:
  if (priv->thr_callbacks.leave_thread) {
    /* fire the leave_thread callback when we need to. We need to do this before
     * we signal the task and with the task lock released. */
    GST_OBJECT_UNLOCK (task);
    priv->thr_callbacks.leave_thread (task, tself, priv->thr_user_data);
    GST_OBJECT_LOCK (task);
  } else {
    /* restore normal priority when releasing back into the pool, we will not
     * touch the priority when a custom callback has been installed. */
    g_thread_set_priority (tself, G_THREAD_PRIORITY_NORMAL);
  }
  /* now we allow messing with the lock again by setting the running flag to
   * FALSE. Together with the SIGNAL this is the sign for the _join() to
   * complete.
   * Note that we still have not dropped the final ref on the task. We could
   * check here if there is a pending join() going on and drop the last ref
   * before releasing the lock as we can be sure that a ref is held by the
   * caller of the join(). */
  task->running = FALSE;
  GST_TASK_SIGNAL (task);
  GST_OBJECT_UNLOCK (task);

  GST_DEBUG ("Exit task %p, thread %p", task, g_thread_self ());

  gst_object_unref (task);
  return;

no_lock:
  {
    g_warning ("starting task without a lock");
    goto exit;
  }
}
static gboolean
gst_hls_demux_src_event (GstPad * pad, GstEvent * event)
{
  GstHLSDemux *demux;

  demux = GST_HLS_DEMUX (gst_pad_get_element_private (pad));

  switch (event->type) {
    case GST_EVENT_SEEK:
    {
      gdouble rate;
      GstFormat format;
      GstSeekFlags flags;
      GstSeekType start_type, stop_type;
      gint64 start, stop;
      GList *walk;
      GstClockTime current_pos, target_pos;
      gint current_sequence;
      GstM3U8MediaFile *file;

      GST_INFO_OBJECT (demux, "Received GST_EVENT_SEEK");

      if (gst_m3u8_client_is_live (demux->client)) {
        GST_WARNING_OBJECT (demux, "Received seek event for live stream");
        return FALSE;
      }

      gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
          &stop_type, &stop);

      if (format != GST_FORMAT_TIME)
        return FALSE;

      GST_DEBUG_OBJECT (demux, "seek event, rate: %f start: %" GST_TIME_FORMAT
          " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start),
          GST_TIME_ARGS (stop));

      GST_M3U8_CLIENT_LOCK (demux->client);
      file = GST_M3U8_MEDIA_FILE (demux->client->current->files->data);
      current_sequence = file->sequence;
      current_pos = 0;
      target_pos = (GstClockTime) start;
      for (walk = demux->client->current->files; walk; walk = walk->next) {
        file = walk->data;

        current_sequence = file->sequence;
        if (current_pos <= target_pos
            && target_pos < current_pos + file->duration) {
          break;
        }
        current_pos += file->duration;
      }
      GST_M3U8_CLIENT_UNLOCK (demux->client);

      if (walk == NULL) {
        GST_WARNING_OBJECT (demux, "Could not find seeked fragment");
        return FALSE;
      }

      if (flags & GST_SEEK_FLAG_FLUSH) {
        GST_DEBUG_OBJECT (demux, "sending flush start");
        gst_pad_push_event (demux->srcpad, gst_event_new_flush_start ());
      }

      demux->cancelled = TRUE;
      gst_task_pause (demux->task);
      g_mutex_lock (demux->fetcher_lock);
      gst_hls_demux_stop_fetcher_locked (demux, TRUE);
      g_mutex_unlock (demux->fetcher_lock);
      gst_hls_demux_stop_update (demux);
      gst_task_pause (demux->task);

      /* wait for streaming to finish */
      g_static_rec_mutex_lock (&demux->task_lock);

      demux->need_cache = TRUE;
      while (!g_queue_is_empty (demux->queue)) {
        GstBuffer *buf = g_queue_pop_head (demux->queue);
        gst_buffer_unref (buf);
      }
      g_queue_clear (demux->queue);
      gst_adapter_clear (demux->download);

      GST_M3U8_CLIENT_LOCK (demux->client);
      GST_DEBUG_OBJECT (demux, "seeking to sequence %d", current_sequence);
      demux->client->sequence = current_sequence;
      gst_m3u8_client_get_current_position (demux->client, &demux->position);
      demux->position_shift = start - demux->position;
      demux->need_segment = TRUE;
      GST_M3U8_CLIENT_UNLOCK (demux->client);


      if (flags & GST_SEEK_FLAG_FLUSH) {
        GST_DEBUG_OBJECT (demux, "sending flush stop");
        gst_pad_push_event (demux->srcpad, gst_event_new_flush_stop ());
      }

      demux->cancelled = FALSE;
      gst_task_start (demux->task);
      g_static_rec_mutex_unlock (&demux->task_lock);

      return TRUE;
    }
    default:
      break;
  }

  return gst_pad_event_default (pad, event);
}
Exemple #19
0
// read continuously until a complete message arrives
static lcm_buf_t *
udp_read_packet (lcm_udpm_t *lcm)
{
    lcm_buf_t *lcmb = NULL;

    int sz = 0;

    // TODO warn about message loss somewhere else.

//    g_static_rec_mutex_lock (&lcm->mutex);
//    unsigned int ring_capacity = lcm_ringbuf_capacity(lcm->ringbuf);
//    unsigned int ring_used = lcm_ringbuf_used(lcm->ringbuf);
//    double buf_avail = ((double)(ring_capacity - ring_used)) / ring_capacity;
//    g_static_rec_mutex_unlock (&lcm->mutex);
//    if (buf_avail < lcm->udp_low_watermark)
//        lcm->udp_low_watermark = buf_avail;
//
//    GTimeVal tv;
//    g_get_current_time(&tv);
//    int elapsedsecs = tv.tv_sec - lcm->udp_last_report_secs;
//    if (elapsedsecs > 2) {
//        uint32_t total_bad = lcm->udp_discarded_bad;
//        if (total_bad > 0 || lcm->udp_low_watermark < 0.5) {
//            fprintf(stderr, 
//                    "%d.%03d LCM loss %4.1f%% : %5d err, "
//                    "buf avail %4.1f%%\n", 
//                   (int) tv.tv_sec, (int) tv.tv_usec/1000,
//                   total_bad * 100.0 / (lcm->udp_rx + total_bad),
//                   lcm->udp_discarded_bad,
//                   100.0 * lcm->udp_low_watermark);
//            
//            lcm->udp_rx = 0;
//            lcm->udp_discarded_bad = 0;
//            lcm->udp_last_report_secs = tv.tv_sec;
//            lcm->udp_low_watermark = HUGE;
//        }
//    }
    
    int got_complete_message = 0;

    while (!got_complete_message) {
        // wait for either incoming UDP data, or for an abort message
        fd_set fds;
        FD_ZERO (&fds);
        FD_SET (lcm->recvfd, &fds);
        FD_SET (lcm->thread_msg_pipe[0], &fds);
        SOCKET maxfd = MAX(lcm->recvfd, lcm->thread_msg_pipe[0]);

        if (select (maxfd + 1, &fds, NULL, NULL, NULL) <= 0) { 
            perror ("udp_read_packet -- select:");
            continue;
        }

        if (FD_ISSET (lcm->thread_msg_pipe[0], &fds)) {
            // received an exit command.
            dbg (DBG_LCM, "read thread received exit command\n");
            if (lcmb) {
                // lcmb is not on one of the memory managed buffer queues.  We could
                // either put it back on one of the queues, or just free it here.  Do the
                // latter.
                //
                // Can also just free its lcm_buf_t here.  Its data buffer is
                // managed either by the ring buffer or the fragment buffer, so
                // we can ignore it.
                free (lcmb);
            }
            return NULL;
        }

        // there is incoming UDP data ready.
        assert (FD_ISSET (lcm->recvfd, &fds));

        if (!lcmb) {
            g_static_rec_mutex_lock (&lcm->mutex);
            lcmb = lcm_buf_allocate_data(lcm->inbufs_empty, &lcm->ringbuf);
            g_static_rec_mutex_unlock (&lcm->mutex);
        }
        struct iovec        vec;
        vec.iov_base = lcmb->buf;
        vec.iov_len = 65535;

        struct msghdr msg;
        memset(&msg, 0, sizeof(struct msghdr));
        msg.msg_name = &lcmb->from;
        msg.msg_namelen = sizeof (struct sockaddr);
        msg.msg_iov = &vec;
        msg.msg_iovlen = 1;
#ifdef MSG_EXT_HDR
        // operating systems that provide SO_TIMESTAMP allow us to obtain more
        // accurate timestamps by having the kernel produce timestamps as soon
        // as packets are received.
        char controlbuf[64];
        msg.msg_control = controlbuf;
        msg.msg_controllen = sizeof (controlbuf);
        msg.msg_flags = 0;
#endif
        sz = recvmsg (lcm->recvfd, &msg, 0);

        if (sz < 0) {
            perror ("udp_read_packet -- recvmsg");
            lcm->udp_discarded_bad++;
            continue;
        }

        if (sz < sizeof(lcm2_header_short_t)) { 
            // packet too short to be LCM
            lcm->udp_discarded_bad++;
            continue;
        }

        lcmb->fromlen = msg.msg_namelen;

        int got_utime = 0;
#ifdef SO_TIMESTAMP
        struct cmsghdr * cmsg = CMSG_FIRSTHDR (&msg);
        /* Get the receive timestamp out of the packet headers if possible */
        while (!lcmb->recv_utime && cmsg) {
            if (cmsg->cmsg_level == SOL_SOCKET &&
                    cmsg->cmsg_type == SCM_TIMESTAMP) {
                struct timeval * t = (struct timeval*) CMSG_DATA (cmsg);
                lcmb->recv_utime = (int64_t) t->tv_sec * 1000000 + t->tv_usec;
                got_utime = 1;
                break;
            }
            cmsg = CMSG_NXTHDR (&msg, cmsg);
        }
#endif
        if (!got_utime)
            lcmb->recv_utime = lcm_timestamp_now ();

        lcm2_header_short_t *hdr2 = (lcm2_header_short_t*) lcmb->buf;
        uint32_t rcvd_magic = ntohl(hdr2->magic);
        if (rcvd_magic == LCM2_MAGIC_SHORT)
            got_complete_message = _recv_short_message (lcm, lcmb, sz);
        else if (rcvd_magic == LCM2_MAGIC_LONG)
            got_complete_message = _recv_message_fragment (lcm, lcmb, sz);
        else {
            dbg (DBG_LCM, "LCM: bad magic\n");
            lcm->udp_discarded_bad++;
            continue;
        }
    }

    // if the newly received packet is a short packet, then resize the space
    // allocated to it on the ringbuffer to exactly match the amount of space
    // required.  That way, we do not use 64k of the ringbuffer for every
    // incoming message.
    if (lcmb->ringbuf) {
        g_static_rec_mutex_lock (&lcm->mutex);
        lcm_ringbuf_shrink_last(lcmb->ringbuf, lcmb->buf, sz);
        g_static_rec_mutex_unlock (&lcm->mutex);
    }

    return lcmb;
}
Exemple #20
0
static RSFilterResponse *
get_image(RSFilter *filter, const RSFilterRequest *request)
{
	RSDcp *dcp = RS_DCP(filter);
	RSDcpClass *klass = RS_DCP_GET_CLASS(dcp);
	GdkRectangle *roi;
	RSFilterResponse *previous_response;
	RSFilterResponse *response;
	RS_IMAGE16 *input;
	RS_IMAGE16 *output;
	RS_IMAGE16 *tmp;

	gint j;

	RSFilterRequest *request_clone = rs_filter_request_clone(request);

	if (!dcp->use_profile)
	{
		gfloat premul[4] = {dcp->pre_mul.x, dcp->pre_mul.y, dcp->pre_mul.z, 1.0};
		rs_filter_param_set_float4(RS_FILTER_PARAM(request_clone), "premul", premul);
	}

	rs_filter_param_set_object(RS_FILTER_PARAM(request_clone), "colorspace", klass->prophoto);
	previous_response = rs_filter_get_image(filter->previous, request_clone);
	g_object_unref(request_clone);

	if (!RS_IS_FILTER(filter->previous))
		return previous_response;

	input = rs_filter_response_get_image(previous_response);
	if (!input) return previous_response;
	response = rs_filter_response_clone(previous_response);

	/* We always deliver in ProPhoto */
	rs_filter_param_set_object(RS_FILTER_PARAM(response), "colorspace", klass->prophoto);
	g_object_unref(previous_response);

	if ((roi = rs_filter_request_get_roi(request)))
	{
		/* Align so we start at even pixel counts */
		roi->width += (roi->x&1);
		roi->x -= (roi->x&1);
		roi->width = MIN(input->w - roi->x, roi->width);
		output = rs_image16_copy(input, FALSE);
		tmp = rs_image16_new_subframe(output, roi);
		bit_blt((char*)GET_PIXEL(tmp,0,0), tmp->rowstride * 2, 
			(const char*)GET_PIXEL(input,roi->x,roi->y), input->rowstride * 2, tmp->w * tmp->pixelsize * 2, tmp->h);
	}
	else
	{
		output = rs_image16_copy(input, TRUE);
		tmp = g_object_ref(output);
	}
	g_object_unref(input);
	rs_filter_response_set_image(response, output);
	g_object_unref(output);

	g_static_rec_mutex_lock(&dcp_mutex);
	init_exposure(dcp);

	guint i, y_offset, y_per_thread, threaded_h;
	guint threads = rs_get_number_of_processor_cores();
	if (tmp->h * tmp->w < 200*200)
		threads = 1;

	ThreadInfo *t = g_new(ThreadInfo, threads);

	threaded_h = tmp->h;
	y_per_thread = (threaded_h + threads-1)/threads;
	y_offset = 0;

	for (i = 0; i < threads; i++)
	{
		t[i].tmp = tmp;
		t[i].start_y = y_offset;
		t[i].start_x = 0;
		t[i].dcp = dcp;
		y_offset += y_per_thread;
		y_offset = MIN(tmp->h, y_offset);
		t[i].end_y = y_offset;
		for(j = 0; j < 256; j++)
			t[i].curve_input_values[j] = 0;
		t[i].single_thread = (threads == 1);
		if (threads == 1)
			start_single_dcp_thread(&t[0]);
		else	
			t[i].threadid = g_thread_create(start_single_dcp_thread, &t[i], TRUE, NULL);
	}

	/* Wait for threads to finish */
	for(i = 0; threads > 1 && i < threads; i++)
		g_thread_join(t[i].threadid);

	/* Settings can change now */
	g_static_rec_mutex_unlock(&dcp_mutex);

	/* If we must deliver histogram data, do it now */
	if (dcp->read_out_curve)
	{
		gint *values = g_malloc0(256*sizeof(gint));
		for(i = 0; i < threads; i++)
			for(j = 0; j < 256; j++)
				values[j] += t[i].curve_input_values[j];
		rs_curve_set_histogram_data(RS_CURVE_WIDGET(dcp->read_out_curve), values);
		g_free(values);
	}
	g_free(t);
	g_object_unref(tmp);

	return response;
}
/** Open connection to the 3e server and authenticate user.
 *
 * This function will do nothing and return TRUE if connection is already
 * opened.
 *
 * @param cb 3E calendar backend.
 * @param err Error pointer.
 *
 * @return TRUE if connection was already open, FALSE on error.
 */
gboolean e_cal_backend_3e_open_connection(ECalBackend3e *cb, GError * *err)
{
    GError *local_err = NULL;

    g_return_val_if_fail(cb != NULL, FALSE);
    g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

    cb->priv->last_conn_failed = FALSE;

    /* if user tried to open connection in offline mode, close current connection
       if any and return error. this shouldn't happen, but let's check it anyway */
    if (!e_backend_get_online(E_BACKEND(cb)))
    {
        g_set_error(err, 0, -1, "Can't open 3e server connection in offline mode.");
        e_cal_backend_3e_close_connection(cb);
        return FALSE;
    }

    g_static_rec_mutex_lock(&cb->priv->conn_mutex);

    /* resolve server URI from DNS TXT if necessary */
    if (cb->priv->server_uri == NULL)
    {
        char *server_hostname = get_eee_server_hostname(cb->priv->username);
        if (server_hostname == NULL)
        {
            g_set_error(err, 0, -1, "Can't resolve server URI for username '%s'", cb->priv->username);
            goto err;
        }
        cb->priv->server_uri = g_strdup_printf("https://%s/RPC2", server_hostname);
        g_free(server_hostname);
    }

    /* check that we have all info that is necessary to create conn */
    if (cb->priv->username == NULL || cb->priv->password == NULL || cb->priv->server_uri == NULL)
    {
        g_set_error(err, 0, -1, "Connection was not setup correctly, can't open.");
        goto err;
    }

    /* create conn object */
    if (cb->priv->conn == NULL)
    {
        cb->priv->conn = xr_client_new(err);
        if (cb->priv->conn == NULL)
        {
            goto err;
        }
        cb->priv->is_open = FALSE;
    }

    if (cb->priv->is_open)
    {
        /* was already locked in this thread */
        g_static_rec_mutex_unlock(&cb->priv->conn_mutex);
        return TRUE;
    }

    if (!xr_client_open(cb->priv->conn, cb->priv->server_uri, err))
    {
        goto err;
    }

    ESClient_authenticate(cb->priv->conn, cb->priv->username, cb->priv->password, &local_err);
    if (local_err)
    {
        g_propagate_error(err, local_err);
        xr_client_close(cb->priv->conn);
        goto err;
    }

    cb->priv->is_open = TRUE;

    return TRUE;

err:
    cb->priv->last_conn_failed = TRUE;
    g_static_rec_mutex_unlock(&cb->priv->conn_mutex);
    return FALSE;
}
Exemple #22
0
/**
 * oh_dequeue_session_event
 * @sid:
 * @event:
 *
 *
 *
 * Returns:
 **/
SaErrorT oh_dequeue_session_event(SaHpiSessionIdT sid,
                                  SaHpiTimeoutT timeout,
                                  struct oh_event * event,
                                  SaHpiEvtQueueStatusT * eventq_status)
{
        struct oh_session *session = NULL;
        struct oh_event *devent = NULL;
        GTimeVal gfinaltime;
        GAsyncQueue *eventq = NULL;
        SaHpiBoolT subscribed;
        SaErrorT invalid;

        if (sid < 1 || (event == NULL))
                return SA_ERR_HPI_INVALID_PARAMS;

        g_static_rec_mutex_lock(&oh_sessions.lock); /* Locked session table */
        session = g_hash_table_lookup(oh_sessions.table, &sid);
        if (!session) {
                g_static_rec_mutex_unlock(&oh_sessions.lock);
                return SA_ERR_HPI_INVALID_SESSION;
        }

        if (eventq_status) {
                *eventq_status = session->eventq_status;
        }
        session->eventq_status = 0;
        eventq = session->eventq;
        g_async_queue_ref(eventq);
        g_static_rec_mutex_unlock(&oh_sessions.lock);

        if (timeout == SAHPI_TIMEOUT_IMMEDIATE) {
                devent = g_async_queue_try_pop(eventq);
        } else if (timeout == SAHPI_TIMEOUT_BLOCK) {
                while (devent == NULL) {
                        g_get_current_time(&gfinaltime);
                        g_time_val_add(&gfinaltime, 5000000L);
                        devent =
                            g_async_queue_timed_pop(eventq, &gfinaltime);
                        /* compliance with spec page 63 */
                        invalid =
                            oh_get_session_subscription(sid, &subscribed);
                        /* Is the session still open? or still subscribed? */
                        if (invalid || !subscribed) {
                                g_async_queue_unref(eventq);
                                oh_event_free(devent, FALSE);
                                return invalid ? SA_ERR_HPI_INVALID_SESSION
                                    : SA_ERR_HPI_INVALID_REQUEST;
                        }
                }
        } else {
                g_get_current_time(&gfinaltime);
                g_time_val_add(&gfinaltime, (glong) (timeout / 1000));
                devent = g_async_queue_timed_pop(eventq, &gfinaltime);
                invalid = oh_get_session_subscription(sid, &subscribed);
                if (invalid || !subscribed) {
                        g_async_queue_unref(eventq);
                        oh_event_free(devent, FALSE);
                        return invalid ? SA_ERR_HPI_INVALID_SESSION :
                            SA_ERR_HPI_INVALID_REQUEST;
                }
        }
        g_async_queue_unref(eventq);

        if (devent) {
                memcpy(event, devent, sizeof(struct oh_event));
                g_free(devent);
                return SA_OK;
        } else {
                memset(event, 0, sizeof(struct oh_event));
                return SA_ERR_HPI_TIMEOUT;
        }
}
Exemple #23
0
static void __dec_plugin_refcount(struct oh_plugin *p)
{
        g_static_rec_mutex_lock(&p->refcount_lock);
        p->refcount--;
        g_static_rec_mutex_unlock(&p->refcount_lock);
}
Exemple #24
0
void ohoi_entity_event(enum ipmi_update_e       op,
                       ipmi_domain_t            *domain,
                       ipmi_entity_t            *entity,
                       void                     *cb_data)
{
    struct oh_handler_state *handler = cb_data;
    struct ohoi_handler *ipmi_handler = handler->data;
    int rv;
    int inst=0;

    inst=ipmi_entity_get_entity_instance(entity);
    if(inst >=96) {
        inst = inst - 96;
    }
    g_static_rec_mutex_lock(&ipmi_handler->ohoih_lock);
    switch (op) {
    case IPMI_ADDED:
        add_entity_event(domain, entity, handler);
        trace_ipmi_entity("ADDED", inst, entity);

        /* entity presence overall */
        rv = ipmi_entity_add_presence_handler(entity,
                                              entity_presence,
                                              handler);
        if (rv)
            dbg("ipmi_entity_set_presence_handler: %#x", rv);

        /* hotswap handler */
        rv = ipmi_entity_add_hot_swap_handler(entity,
                                              ohoi_hot_swap_cb,
                                              cb_data);
        if(rv)
            dbg("Failed to set entity hot swap handler");

        /* sensors */
        rv= ipmi_entity_add_sensor_update_handler(entity,
                ohoi_sensor_event,
                handler);
        if (rv) {
            dbg("ipmi_entity_set_sensor_update_handler: %#x", rv);
            break;
        }
        /* controls */
        rv = ipmi_entity_add_control_update_handler(entity,
                ohoi_control_event,
                handler);

        if (rv) {
            dbg("ipmi_entity_set_control_update_handler: %#x", rv);
            return;
        }
        /* inventory (a.k.a FRU) */
        rv = ipmi_entity_add_fru_update_handler(entity,
                                                ohoi_inventory_event,
                                                handler);
        if (rv) {
            dbg("ipmi_entity_set_fru_update_handler: %#x", rv);
            break;
        }
        break;

    case IPMI_DELETED:
        delete_entity(handler, entity);
        trace_ipmi_entity("DELETED", inst, entity);
        break;

    case IPMI_CHANGED:
        change_entity(handler, entity);
        trace_ipmi_entity("CHANGED", inst, entity);
        break;
    default:
        dbg("Entity: Unknow change?!");
    }
    g_static_rec_mutex_unlock(&ipmi_handler->ohoih_lock);
}
Exemple #25
0
static void __dec_handler_refcount(struct oh_handler *h)
{
        g_static_rec_mutex_lock(&h->refcount_lock);
        h->refcount--;
        g_static_rec_mutex_unlock(&h->refcount_lock);
}
Exemple #26
0
static int 
lcm_udpm_handle (lcm_udpm_t *lcm)
{
    int status;
    char ch;

    if (! lcm->thread_created) {
        if (0 != _setup_recv_thread (lcm))
            return -1;
    }

    /* Read one byte from the notify pipe.  This will block if no packets are
     * available yet and wake up when they are. */
    status = lcm_internal_pipe_read(lcm->notify_pipe[0], &ch, 1);
    if (status == 0) {
        fprintf (stderr, "Error: lcm_handle read 0 bytes from notify_pipe\n");
        return -1;
    }
    else if (status < 0) {
        fprintf (stderr, "Error: lcm_handle read: %s\n", strerror (errno));
        return -1;
    }

    /* Dequeue the next received packet */
    g_static_rec_mutex_lock (&lcm->mutex);
    lcm_buf_t * lcmb = lcm_buf_dequeue (lcm->inbufs_filled);

    if (!lcmb) {
        fprintf (stderr, 
                "Error: no packet available despite getting notification.\n");
        g_static_rec_mutex_unlock (&lcm->mutex);
        return -1;
    }

    /* If there are still packets in the queue, put something back in the pipe
     * so that future invocations will get called. */
    if (!is_buf_queue_empty (lcm->inbufs_filled))
        if (lcm_internal_pipe_write(lcm->notify_pipe[1], "+", 1) < 0)
            perror ("write to notify");
    g_static_rec_mutex_unlock (&lcm->mutex);

    lcm_recv_buf_t rbuf;
    rbuf.data = (uint8_t*) lcmb->buf + lcmb->data_offset;
    rbuf.data_size = lcmb->data_size;
    rbuf.recv_utime = lcmb->recv_utime;
    rbuf.lcm = lcm->lcm;

    lcm_dispatch_handlers (lcm->lcm, &rbuf, lcmb->channel_name);

    g_static_rec_mutex_lock (&lcm->mutex);
    if (lcmb->buf_from_ringbuf)
        lcm_ringbuf_dealloc (lcm->ringbuf, lcmb->buf);
    else
        free (lcmb->buf);
    lcmb->buf = NULL;
    lcmb->buf_size = 0;
    lcm_buf_enqueue (lcm->inbufs_empty, lcmb);
    g_static_rec_mutex_unlock (&lcm->mutex);

    return 0;
}
void
_mate_vfs_async_job_map_unlock (void)
{
    async_job_map_locked--;
    g_static_rec_mutex_unlock (&async_job_map_lock);
}
static void
_threads_leave (void)
{
	g_static_rec_mutex_unlock (&rb_gdk_mutex);
}
void ohoi_control_event(enum ipmi_update_e op,
                        ipmi_entity_t      *ent,
                        ipmi_control_t     *control,
                        void               *cb_data)
{
    struct oh_handler_state *handler = cb_data;
    struct ohoi_handler *ipmi_handler = handler->data;
    struct ohoi_resource_info *ohoi_res_info;
    int ctrl_type = ipmi_control_get_type(control);
    ipmi_control_id_t cid = ipmi_control_convert_to_id(control);


    ipmi_entity_id_t	entity_id;
    SaHpiRptEntryT		*rpt_entry;
    char str[24];
    int rv;

    entity_id = ipmi_entity_convert_to_id(ent);
    rpt_entry = ohoi_get_resource_by_entityid(handler->rptcache,
                &entity_id);

    if (!rpt_entry) {
        dump_entity_id("Control with RPT Entry?!", entity_id);
        return;
    }

    g_static_rec_mutex_lock(&ipmi_handler->ohoih_lock);
    ohoi_res_info = oh_get_resource_data(handler->rptcache,
                                         rpt_entry->ResourceId);

    if (op == IPMI_ADDED) {
        trace_ipmi_control("ADD", control, rpt_entry);
        /* attach power and reset to chassis entity since
           IPMI provides them as such */
        switch (ctrl_type) {
        case IPMI_CONTROL_ONE_SHOT_RESET:
            ohoi_res_info->reset_ctrl = cid;
            rpt_entry->ResourceCapabilities |=
                SAHPI_CAPABILITY_RESET;
            break;
        case IPMI_CONTROL_POWER:
            if ((ipmi_handler->d_type == IPMI_DOMAIN_TYPE_ATCA) &&
                    (ipmi_entity_get_entity_id(ent) ==
                     SAHPI_ENT_SYSTEM_CHASSIS)) {
                // never power off ATCA chassis
                break;
            }
            ohoi_res_info->power_ctrl = cid;
            rpt_entry->ResourceCapabilities |=
                SAHPI_CAPABILITY_POWER;
            break;
        case IPMI_CONTROL_ALARM:
            rv = add_alarm_rdrs(handler,rpt_entry,control);
            if (rv) {
                dbg("add_alarms_rdrs failed");
                break;
            }
            rpt_entry->ResourceCapabilities |=
                SAHPI_CAPABILITY_CONTROL |
                SAHPI_CAPABILITY_RDR;
            break;
        case IPMI_CONTROL_IDENTIFIER:
#if 0
            rv = address_control_get(control,handler, ent, rpt_entry);
            if (rv) {
                dbg("address_control_get failed");
                break;
            }
            rpt_entry->ResourceCapabilities |=
                SAHPI_CAPABILITY_CONTROL |
                SAHPI_CAPABILITY_RDR;
#endif
            break;
        case IPMI_CONTROL_LIGHT:
            ipmi_control_get_id(control, str, 24);
            if (add_led_control_event(ent, control, handler, rpt_entry)) {
                break;
            }
            rpt_entry->ResourceCapabilities |=
                SAHPI_CAPABILITY_CONTROL |
                SAHPI_CAPABILITY_RDR;
            break;
        default:
            if (SA_OK != add_control_event(ent, control, handler,
                                           rpt_entry->ResourceEntity,
                                           rpt_entry->ResourceId)) {
                break;
            }
            rpt_entry->ResourceCapabilities |=
                SAHPI_CAPABILITY_CONTROL |
                SAHPI_CAPABILITY_RDR;
            break;
        }
    } else if (op == IPMI_DELETED) {
        trace_ipmi_control("DELETE", control, rpt_entry);
        switch (ctrl_type) {
        case IPMI_CONTROL_ONE_SHOT_RESET:
            ipmi_control_id_set_invalid(
                &ohoi_res_info->reset_ctrl);
            rpt_entry->ResourceCapabilities &=
                ~SAHPI_CAPABILITY_RESET;
            break;
        case IPMI_CONTROL_POWER:
            ipmi_control_id_set_invalid(
                &ohoi_res_info->power_ctrl);
            rpt_entry->ResourceCapabilities &=
                ~SAHPI_CAPABILITY_POWER;
            break;
        default:
            if (ohoi_delete_orig_control_rdr(handler,
                                             rpt_entry, &cid)) {
                // no more controlss for rpt
                rpt_entry->ResourceCapabilities &=
                    ~SAHPI_CAPABILITY_CONTROL;
                ohoi_res_info->ctrl_count = 0;
            }
            break;
        }
        if ((oh_get_rdr_next(handler->rptcache, rpt_entry->ResourceId,
                             SAHPI_FIRST_ENTRY) == NULL) &&
                (ohoi_res_info->fru == NULL)) {
            // no more rdrs for rpt
            rpt_entry->ResourceCapabilities &=
                ~SAHPI_CAPABILITY_RDR;
        }
    }
    trace_ipmi("Set updated for res_info %p(%d). Control", ohoi_res_info, rpt_entry->ResourceId);
    entity_rpt_set_updated(ohoi_res_info, ipmi_handler);
    g_static_rec_mutex_unlock(&ipmi_handler->ohoih_lock);
}
Exemple #30
0
static struct oh_handler *new_handler(GHashTable *handler_config)
{       /* Return a new oh_handler instance */
        struct oh_plugin *plugin = NULL;
        struct oh_handler *handler = NULL;
        static unsigned int handler_id = 1;
        unsigned int *hidp;
        char *hid_strp;

        if (!handler_config) {
                dbg("ERROR creating new handler. Invalid parameter.");
                return NULL;
        }

        handler = (struct oh_handler *)g_malloc0(sizeof(struct oh_handler));
        if (!handler) {
                dbg("Out of Memory!");
                return NULL;
        }

        hidp = (unsigned int *)g_malloc(sizeof(unsigned int));
        if (!hidp) {
                dbg("Out of Memory!");
                g_free(handler);
                return NULL;
        }
        hid_strp = strdup("handler-id");
        if (!hid_strp) {
                dbg("Out of Memory!");
                g_free(handler);
                g_free(hidp);
                return NULL;
        }

        plugin = oh_get_plugin((char *)g_hash_table_lookup(handler_config, "plugin"));
        if(!plugin) {
                dbg("Attempt to create handler for unknown plugin %s",
                    (char *)g_hash_table_lookup(handler_config, "plugin"));
                goto cleanexit;
        }
        /* Initialize handler */
        handler->abi = plugin->abi;
        plugin->handler_count++; /* Increment # of handlers using the plugin */
        oh_release_plugin(plugin);
        g_static_rec_mutex_lock(&oh_handlers.lock);
        handler->id = handler_id++;
        g_static_rec_mutex_unlock(&oh_handlers.lock);
        *hidp = handler->id;
        g_hash_table_insert(handler_config, (gpointer)hid_strp,(gpointer)hidp);
        handler->plugin_name = (char *)g_hash_table_lookup(handler_config, "plugin");
        handler->config = handler_config;
        handler->dids = NULL;
        handler->refcount = 0;
        g_static_rec_mutex_init(&handler->lock);
        g_static_rec_mutex_init(&handler->refcount_lock);

        return handler;
cleanexit:
        g_free(hidp);
        g_free(hid_strp);
        g_free(handler);
        return NULL;
}