Beispiel #1
0
void
client_close(struct client *client)
{
	client_list_remove(client);

	client_set_expired(client);

	g_timer_destroy(client->last_activity);

	if (client->cmd_list) {
		free_cmd_list(client->cmd_list);
		client->cmd_list = NULL;
	}

	g_queue_foreach(client->deferred_send, deferred_buffer_free, NULL);
	g_queue_free(client->deferred_send);

	fifo_buffer_free(client->input);

	g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE,
	      "[%u] closed", client->num);
	g_free(client);
}
/* Called with handle_hash lock held */
static void
destroy_monitor_handle (GnomeVFSMonitorHandle *handle)
{
	gboolean res;

	if (handle->pending_timeout) 
		g_source_remove (handle->pending_timeout);
	
	g_queue_foreach (handle->pending_callbacks, (GFunc) free_callback_data, NULL);
	g_queue_free (handle->pending_callbacks);
	handle->pending_callbacks = NULL;
	
	res = g_hash_table_remove (handle_hash, handle->method_handle);
	if (!res) {
		g_warning ("gnome-vfs-monitor.c: A monitor handle was destroyed "
			   "before it was added to the method hash table. This "
			   "is a bug in the application and can cause crashes. "
			   "It is probably a race-condition.");
	}

	gnome_vfs_uri_unref (handle->uri);
	g_free (handle);
}
Beispiel #3
0
void
gst_droidcamsrc_dev_stop (GstDroidCamSrcDev * dev)
{
  g_rec_mutex_lock (dev->lock);

  GST_DEBUG ("dev stop");

  if (dev->running) {
    GST_DEBUG ("stopping preview");
    gst_buffer_pool_set_active (dev->pool, FALSE);
    droid_media_camera_stop_preview (dev->cam);
    dev->running = FALSE;
    GST_DEBUG ("stopped preview");
  }

  /* Now we need to empty the queue */
  g_mutex_lock (&dev->vfsrc->lock);
  g_queue_foreach (dev->vfsrc->queue, (GFunc) gst_buffer_unref, NULL);
  g_queue_clear (dev->vfsrc->queue);
  g_mutex_unlock (&dev->vfsrc->lock);

  g_rec_mutex_unlock (dev->lock);
}
void
passwd_authenticate (PasswdHandler *passwd_handler,
                     const char    *current_password,
                     PasswdCallback cb,
                     const gpointer user_data)
{
        GError *error = NULL;

        /* Don't stop if we've already started chaging password */
        if (passwd_handler->changing_password)
                return;

        /* Clear data from possible previous attempts to change password */
        passwd_handler->new_password = NULL;
        passwd_handler->chpasswd_cb = NULL;
        passwd_handler->chpasswd_cb_data = NULL;
        g_queue_foreach (passwd_handler->backend_stdin_queue, (GFunc) g_free, NULL);
        g_queue_clear (passwd_handler->backend_stdin_queue);

        passwd_handler->current_password = current_password;
        passwd_handler->auth_cb = cb;
        passwd_handler->auth_cb_data = user_data;

        /* Spawn backend */
        stop_passwd (passwd_handler);

        if (!spawn_passwd (passwd_handler, &error)) {
                g_warning ("%s", error->message);
                g_error_free (error);

                return;
        }

        authenticate (passwd_handler);

        /* Our IO watcher should now handle the rest */
}
void
httpd_client_free(struct httpd_client *client)
{
	assert(client != NULL);

	if (client->state == RESPONSE) {
		if (client->write_source_id != 0)
			g_source_remove(client->write_source_id);

		if (client->current_page != NULL)
			page_unref(client->current_page);

		g_queue_foreach(client->pages, httpd_client_unref_page, NULL);
		g_queue_free(client->pages);
	} else
		fifo_buffer_free(client->input);

	if (client->metadata)
		page_unref (client->metadata);

	g_source_remove(client->read_source_id);
	g_io_channel_unref(client->channel);
	g_free(client);
}
Beispiel #6
0
void
gdbmi_value_foreach (const GDBMIValue* val, GFunc func, gpointer user_data)
{
	g_return_if_fail (val != NULL);
	g_return_if_fail (func != NULL);
	
	if (val->type == GDBMI_DATA_LIST)
	{
		g_queue_foreach (val->data.list, func, user_data);
	}
	else if (val->type == GDBMI_DATA_HASH)
	{
		struct _GDBMIForeachHashData hash_data = {NULL, NULL};
		
		hash_data.user_callback = func;
		hash_data.user_data = user_data;
		g_hash_table_foreach (val->data.hash, (GHFunc)gdbmi_value_hash_foreach,
							  &hash_data);
	}
	else
	{
		g_warning ("Can not do foreach for GDBMIValue this type");
	}
}
static gboolean
src_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode,
    gboolean active)
{
  GstDtlsEnc *self = GST_DTLS_ENC (parent);
  gboolean success = TRUE;
  g_return_val_if_fail (mode == GST_PAD_MODE_PUSH, FALSE);

  if (active) {
    GST_DEBUG_OBJECT (self, "src pad activating in push mode");

    self->flushing = FALSE;
    self->send_initial_events = TRUE;
    success =
        gst_pad_start_task (pad, (GstTaskFunction) src_task_loop, self->src,
        NULL);
    if (!success) {
      GST_WARNING_OBJECT (self, "failed to activate pad task");
    }
  } else {
    GST_DEBUG_OBJECT (self, "deactivating src pad");

    g_mutex_lock (&self->queue_lock);
    g_queue_foreach (&self->queue, (GFunc) gst_buffer_unref, NULL);
    g_queue_clear (&self->queue);
    self->flushing = TRUE;
    g_cond_signal (&self->queue_cond_add);
    g_mutex_unlock (&self->queue_lock);
    success = gst_pad_stop_task (pad);
    if (!success) {
      GST_WARNING_OBJECT (self, "failed to deactivate pad task");
    }
  }

  return success;
}
Beispiel #8
0
void
mex_proxy_stop (MexProxy *proxy)
{
  MexProxyPrivate *priv;
  GController *controller;

  g_return_if_fail (MEX_IS_PROXY (proxy));

  priv = proxy->priv;

  /* There's nothing to do if there's no model set */
  if (!priv->model)
    {
      priv->started = FALSE;
      return;
    }

  if (!priv->started)
    return;

  controller = mex_model_get_controller (priv->model);
  g_signal_handlers_disconnect_by_func (controller,
                                        mex_proxy_controller_changed_cb,
                                        proxy);

  if (priv->timer_timeout)
    {
      g_source_remove (priv->timer_timeout);
      priv->timer_timeout = 0;
    }

  g_queue_foreach (priv->to_add, (GFunc)g_object_unref, NULL);
  g_queue_clear (priv->to_add);

  priv->started = FALSE;
}
Beispiel #9
0
static void _master_registerHosts(Master* master) {
    MAGIC_ASSERT(master);
    GQueue* hosts = configuration_getHostElements(master->config);
    g_queue_foreach(hosts, (GFunc)_master_registerHostCallback, master);
}
Beispiel #10
0
static void _master_registerHostCallback(ConfigurationHostElement* he, Master* master) {
    MAGIC_ASSERT(master);
    utility_assert(he);
    utility_assert(he->id.isSet && he->id.string);

    guint64 quantity = he->quantity.isSet ? he->quantity.integer : 1;

    for(guint64 i = 0; i < quantity; i++) {
        HostParameters* params = g_new0(HostParameters, 1);

        /* hostname and id params */
        const gchar* hostNameBase = he->id.string->str;

        GString* hostnameBuffer = g_string_new(hostNameBase);
        if(quantity > 1) {
            g_string_append_printf(hostnameBuffer, "%"G_GUINT64_FORMAT, i+1);
        }
        params->hostname = hostnameBuffer->str;

        /* cpu params - if they didnt specify a CPU frequency, use the slave machine frequency */
        gint slaveCPUFreq = slave_getRawCPUFrequency(master->slave);
        params->cpuFrequency = he->cpufrequency.isSet ? he->cpufrequency.integer : (slaveCPUFreq > 0) ? (guint64)slaveCPUFreq : 0;
        if(params->cpuFrequency == 0) {
            params->cpuFrequency = 2500000; // 2.5 GHz
            debug("both configured and raw slave cpu frequencies unavailable, using 2500000 KHz");
        }

        gint defaultCPUThreshold = options_getCPUThreshold(master->options);
        params->cpuThreshold = defaultCPUThreshold > 0 ? defaultCPUThreshold : 0;
        gint defaultCPUPrecision = options_getCPUPrecision(master->options);
        params->cpuPrecision = defaultCPUPrecision > 0 ? defaultCPUPrecision : 0;

        params->logLevel = he->loglevel.isSet ?
                loglevel_fromStr(he->loglevel.string->str) :
                options_getLogLevel(master->options);

        params->heartbeatLogLevel = he->heartbeatloglevel.isSet ?
                loglevel_fromStr(he->heartbeatloglevel.string->str) :
                options_getHeartbeatLogLevel(master->options);

        params->heartbeatInterval = he->heartbeatfrequency.isSet ?
                (SimulationTime)(he->heartbeatfrequency.integer * SIMTIME_ONE_SECOND) :
                options_getHeartbeatInterval(master->options);

        params->heartbeatLogInfo = he->heartbeatloginfo.isSet ?
                options_toHeartbeatLogInfo(master->options, he->heartbeatloginfo.string->str) :
                options_getHeartbeatLogInfo(master->options);

        params->logPcap = (he->logpcap.isSet && !g_ascii_strcasecmp(he->logpcap.string->str, "true")) ? TRUE : FALSE;
        params->pcapDir = he->pcapdir.isSet ? he->pcapdir.string->str : NULL;

        /* socket buffer settings - if size is set manually, turn off autotuning */
        params->recvBufSize = he->socketrecvbuffer.isSet ? he->socketrecvbuffer.integer :
                options_getSocketReceiveBufferSize(master->options);
        params->autotuneRecvBuf = he->socketrecvbuffer.isSet ? FALSE :
                options_doAutotuneReceiveBuffer(master->options);

        params->sendBufSize = he->socketsendbuffer.isSet ? he->socketsendbuffer.integer :
                options_getSocketSendBufferSize(master->options);
        params->autotuneSendBuf = he->socketsendbuffer.isSet ? FALSE :
                options_doAutotuneSendBuffer(master->options);

        params->interfaceBufSize = he->interfacebuffer.isSet ? he->interfacebuffer.integer :
                options_getInterfaceBufferSize(master->options);
        params->qdisc = options_getQueuingDiscipline(master->options);

        /* requested attributes from shadow config */
        params->ipHint = he->ipHint.isSet ? he->ipHint.string->str : NULL;
        params->countrycodeHint = he->countrycodeHint.isSet ? he->countrycodeHint.string->str : NULL;
        params->citycodeHint = he->citycodeHint.isSet ? he->citycodeHint.string->str : NULL;
        params->geocodeHint = he->geocodeHint.isSet ? he->geocodeHint.string->str : NULL;
        params->typeHint = he->typeHint.isSet ? he->typeHint.string->str : NULL;
        params->requestedBWDownKiBps = he->bandwidthdown.isSet ? he->bandwidthdown.integer : 0;
        params->requestedBWUpKiBps = he->bandwidthup.isSet ? he->bandwidthup.integer : 0;

        slave_addNewVirtualHost(master->slave, params);

        ProcessCallbackArgs processArgs;
        processArgs.master = master;
        processArgs.hostParams = params;

        /* now handle each virtual process the host will run */
        g_queue_foreach(he->processes, (GFunc)_master_registerProcessCallback, &processArgs);

        /* cleanup for next pass through the loop */
        g_string_free(hostnameBuffer, TRUE);
        g_free(params);
    }
}
Beispiel #11
0
static void _master_registerPlugins(Master* master) {
    MAGIC_ASSERT(master);

    GQueue* plugins = configuration_getPluginElements(master->config);
    g_queue_foreach(plugins, (GFunc)_master_registerPluginCallback, master);
}
gboolean
_gtk_source_language_file_parse_version2 (GtkSourceLanguage       *language,
					  GtkSourceContextData    *ctx_data)
{
	GHashTable *defined_regexes, *styles;
	gboolean success;
	GError *error = NULL;
	gchar *filename;
	GHashTable *loaded_lang_ids;
	GQueue *replacements;

	g_return_val_if_fail (ctx_data != NULL, FALSE);

	filename = language->priv->lang_file_name;

	/* TODO: as an optimization tell the parser to merge CDATA
	 * as text nodes (XML_PARSE_NOCDATA), and to ignore blank
	 * nodes (XML_PARSE_NOBLANKS), if it is possible with
	 * xmlTextReader. */
	xmlKeepBlanksDefault (0);
	xmlLineNumbersDefault (1);
	xmlSubstituteEntitiesDefault (1);
	DEBUG (xmlPedanticParserDefault (1));

	defined_regexes = g_hash_table_new_full (g_str_hash, g_str_equal,
						 g_free, g_free);
	styles = g_hash_table_new_full (g_str_hash,
					g_str_equal,
					g_free,
					(GDestroyNotify) _gtk_source_style_info_free);
	loaded_lang_ids = g_hash_table_new_full (g_str_hash, g_str_equal,
						 (GDestroyNotify) xmlFree,
						 NULL);
	replacements = g_queue_new ();

	success = file_parse (filename, language, ctx_data,
			      defined_regexes, styles,
			      loaded_lang_ids, replacements,
			      &error);

	if (success)
		success = _gtk_source_context_data_finish_parse (ctx_data, replacements->head, &error);

	if (success)
		g_hash_table_foreach_steal (styles,
					    (GHRFunc) steal_styles_mapping,
					    language->priv->styles);

	g_queue_foreach (replacements, (GFunc) _gtk_source_context_replace_free, NULL);
	g_queue_free (replacements);
	g_hash_table_destroy (loaded_lang_ids);
	g_hash_table_destroy (defined_regexes);
	g_hash_table_destroy (styles);

	if (!success)
	{
		g_warning ("Failed to load '%s': %s",
			   filename, error->message);
		g_error_free (error);
		return FALSE;
	}

	return TRUE;
}
static GstStateChangeReturn
gst_decklink_video_src_change_state (GstElement * element,
    GstStateChange transition)
{
  GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (element);
  GstStateChangeReturn ret;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (!gst_decklink_video_src_open (self)) {
        ret = GST_STATE_CHANGE_FAILURE;
        goto out;
      }
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      g_mutex_lock (&self->input->lock);
      self->input->clock_start_time = GST_CLOCK_TIME_NONE;
      self->input->clock_last_time = 0;
      self->input->clock_offset = 0;
      g_mutex_unlock (&self->input->lock);
      gst_element_post_message (element,
          gst_message_new_clock_provide (GST_OBJECT_CAST (element),
              self->input->clock, TRUE));
      self->flushing = FALSE;
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:{
      GstClock *clock;

      clock = gst_element_get_clock (GST_ELEMENT_CAST (self));
      if (clock && clock != self->input->clock) {
        gst_clock_set_master (self->input->clock, clock);
      }
      if (clock)
        gst_object_unref (clock);

      break;
    }
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_element_post_message (element,
          gst_message_new_clock_lost (GST_OBJECT_CAST (element),
              self->input->clock));
      gst_clock_set_master (self->input->clock, NULL);
      // Reset calibration to make the clock reusable next time we use it
      gst_clock_set_calibration (self->input->clock, 0, 0, 1, 1);
      g_mutex_lock (&self->input->lock);
      self->input->clock_start_time = GST_CLOCK_TIME_NONE;
      self->input->clock_last_time = 0;
      self->input->clock_offset = 0;
      g_mutex_unlock (&self->input->lock);

      g_queue_foreach (&self->current_frames, (GFunc) capture_frame_free, NULL);
      g_queue_clear (&self->current_frames);
      self->caps_mode = GST_DECKLINK_MODE_AUTO;
      break;
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:{
      HRESULT res;

      GST_DEBUG_OBJECT (self, "Stopping streams");
      g_mutex_lock (&self->input->lock);
      self->input->started = FALSE;
      g_mutex_unlock (&self->input->lock);

      res = self->input->input->StopStreams ();
      if (res != S_OK) {
        GST_ELEMENT_ERROR (self, STREAM, FAILED,
            (NULL), ("Failed to stop streams: 0x%08x", res));
        ret = GST_STATE_CHANGE_FAILURE;
      }
      self->internal_base_time = GST_CLOCK_TIME_NONE;
      self->external_base_time = GST_CLOCK_TIME_NONE;
      break;
    }
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:{
      g_mutex_lock (&self->input->lock);
      if (self->input->start_streams)
        self->input->start_streams (self->input->videosrc);
      g_mutex_unlock (&self->input->lock);

      break;
    }
    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_decklink_video_src_close (self);
      break;
    default:
      break;
  }
out:

  return ret;
}
static gboolean
negotiate_profile_and_level (GstCapsFeatures * features, GstStructure * s,
    gpointer user_data)
{
  struct ProfileLevelCtx *ctx = user_data;
  GstV4l2Object *v4l2object = GST_V4L2_VIDEO_ENC (ctx->self)->v4l2output;
  GQueue profiles = G_QUEUE_INIT;
  GQueue levels = G_QUEUE_INIT;
  gboolean failed = FALSE;

  if (get_string_list (s, "profile", &profiles)) {
    GList *l;

    for (l = profiles.head; l; l = l->next) {
      struct v4l2_control control = { 0, };
      gint v4l2_profile;
      const gchar *profile = l->data;

      GST_TRACE_OBJECT (ctx->self, "Trying profile %s", profile);

      control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
      control.value = v4l2_profile = v4l2_profile_from_string (profile);

      if (control.value < 0)
        continue;

      if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0) {
        GST_WARNING_OBJECT (ctx->self, "Failed to set H264 profile: '%s'",
            g_strerror (errno));
        break;
      }

      profile = v4l2_profile_to_string (control.value);

      if (control.value == v4l2_profile) {
        ctx->profile = profile;
        break;
      }

      if (g_list_find_custom (l, profile, g_str_equal)) {
        ctx->profile = profile;
        break;
      }
    }

    if (profiles.length && !ctx->profile)
      failed = TRUE;

    g_queue_foreach (&profiles, (GFunc) g_free, NULL);
    g_queue_clear (&profiles);
  }

  if (!failed && get_string_list (s, "level", &levels)) {
    GList *l;

    for (l = levels.head; l; l = l->next) {
      struct v4l2_control control = { 0, };
      gint v4l2_level;
      const gchar *level = l->data;

      GST_TRACE_OBJECT (ctx->self, "Trying level %s", level);

      control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
      control.value = v4l2_level = v4l2_level_from_string (level);

      if (control.value < 0)
        continue;

      if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_CTRL, &control) < 0) {
        GST_WARNING_OBJECT (ctx->self, "Failed to set H264 level: '%s'",
            g_strerror (errno));
        break;
      }

      level = v4l2_level_to_string (control.value);

      if (control.value == v4l2_level) {
        ctx->level = level;
        break;
      }

      if (g_list_find_custom (l, level, g_str_equal)) {
        ctx->level = level;
        break;
      }
    }

    if (levels.length && !ctx->level)
      failed = TRUE;

    g_queue_foreach (&levels, (GFunc) g_free, NULL);
    g_queue_clear (&levels);
  }

  /* If it failed, we continue */
  return failed;
}
Beispiel #15
0
void fm_list_clear (gpointer list)
{
    g_queue_foreach ( (GQueue*)list,  (GFunc)FM_LIST (list)->funcs->item_unref, NULL);
    g_queue_clear ( (GQueue*)list);
}
Beispiel #16
0
/**
 * g_queue_free_full:
 * @queue: a pointer to a #GQueue
 * @free_func: the function to be called to free each element's data
 *
 * Convenience method, which frees all the memory used by a #GQueue,
 * and calls the specified destroy function on every element's data.
 *
 * Since: 2.32
 */
void
g_queue_free_full (GQueue * queue, GDestroyNotify free_func)
{
    g_queue_foreach (queue, (GFunc) free_func, NULL);
    g_queue_free (queue);
}
Beispiel #17
0
void fec_dec_push_fec_packet(fec_dec *dec, GstBuffer *packet)
{
    guint8 *fec_data;
    guint32 snbase;
    guint16 seqnum;
    GList *link;

    fec_data = GST_BUFFER_DATA(packet) + gst_rtp_buffer_get_header_len(packet);
    snbase = (((guint16)(fec_data[0])) << 8) | (((guint16)(fec_data[1])) << 0);
    seqnum = gst_rtp_buffer_get_seq(packet);

    GST_DEBUG("Received FEC packet, snbase %u, index %u, seqnum %u", snbase, (guint)(fec_data[12]), seqnum);

    if (snbase == dec->blacklisted_snbase)
    {
        GST_DEBUG("Ignoring FEC packet since data from this snbase has been restored already (= the packet is not needed)");
        return;
    }

    if (g_hash_table_lookup_extended(dec->fec_packet_set, GINT_TO_POINTER(seqnum), NULL, NULL))
    {
        GST_DEBUG("FEC packet with seqnum %u is already in queue - discarding duplicate", seqnum);
        return;
    }

    if (dec->cur_snbase != snbase)
    {
        GST_DEBUG("snbase changed from %u to %u - purging FEC queue (%u FEC packets and %u media packets present)", dec->cur_snbase, snbase, dec->num_received_fec_packets, dec->num_received_media_packets);
        g_queue_foreach(dec->fec_packets, fec_dec_clear_packet, NULL);
        g_queue_clear(dec->fec_packets);
        g_hash_table_remove_all(dec->fec_packet_set);
        dec->num_received_fec_packets = 0;
    }

    dec->cur_snbase = snbase;
    dec->has_snbase = TRUE;
    dec->received_media_packet_mask = 0;
    dec->num_received_media_packets = 0;
    dec->max_packet_size = 0;
    g_queue_push_tail(dec->fec_packets, gst_buffer_ref(packet));
    g_hash_table_add(dec->fec_packet_set, GINT_TO_POINTER(seqnum));
    ++dec->num_received_fec_packets;

    for (link = g_queue_peek_head_link(dec->media_packets); link != NULL;)
    {
        GstBuffer *media_packet;
        guint32 corrected_seqnum;

        media_packet = link->data;
        seqnum = gst_rtp_buffer_get_seq(media_packet);
        corrected_seqnum = fec_dec_correct_seqnum(dec, seqnum);

        if ((corrected_seqnum < snbase) || (corrected_seqnum > (snbase + dec->num_media_packets - 1)))
        {
            GList *old_link;

            GST_DEBUG("Found media packet with seqnum %u outside bounds [%u, %u] - purging", seqnum, snbase, snbase + dec->num_media_packets - 1);
            g_hash_table_remove(dec->media_packet_set, GINT_TO_POINTER(seqnum));
            gst_buffer_unref(media_packet);

            old_link = link;
            link = link->next;
            g_queue_delete_link(dec->media_packets, old_link);
        }
        else
        {
            dec->max_packet_size = MAX(dec->max_packet_size, GST_BUFFER_SIZE(media_packet));
            dec->received_media_packet_mask |= (1ul << (corrected_seqnum - dec->cur_snbase));
            ++dec->num_received_media_packets;
            link = link->next;
        }
    }

    fec_dec_check_state(dec);
}
Beispiel #18
0
void fec_dec_push_media_packet(fec_dec *dec, GstBuffer *packet)
{
    guint32 original_seqnum;
    original_seqnum = gst_rtp_buffer_get_seq(packet);

    if (g_hash_table_lookup_extended(dec->media_packet_set, GINT_TO_POINTER(original_seqnum), NULL, NULL))
    {
        GST_DEBUG("Media packet with seqnum %u is already in queue - discarding duplicate", original_seqnum);
        return;
    }

    if (dec->has_snbase)
    {
        guint32 corrected_seqnum;
        corrected_seqnum = fec_dec_correct_seqnum(dec, original_seqnum);

        GST_DEBUG("Pushing media packet with seqnum %u, current snbase is %u", original_seqnum, dec->cur_snbase);

        if ((corrected_seqnum - (guint32)(dec->cur_snbase)) >= dec->num_media_packets)
        {
            GST_DEBUG("Distance between FEC packets and incoming media packets is too large - purging %u FEC packets and setting has_snbase to FALSE", dec->num_received_fec_packets);

            dec->has_snbase = FALSE;
            dec->blacklisted_snbase = dec->cur_snbase;
            g_queue_foreach(dec->fec_packets, fec_dec_clear_packet, NULL);
            g_queue_clear(dec->fec_packets);
            g_hash_table_remove_all(dec->fec_packet_set);
            dec->num_received_fec_packets = 0;

            GST_DEBUG("Pushing media packet with seqnum %u, no current snbase set", original_seqnum);
            g_queue_push_tail(dec->media_packets, gst_buffer_ref(packet));
            g_hash_table_add(dec->media_packet_set, GINT_TO_POINTER(original_seqnum));
            ++dec->num_received_media_packets;
        }
        else if ((corrected_seqnum >= (guint32)(dec->cur_snbase)) && (corrected_seqnum <= ((guint32)(dec->cur_snbase) + ((guint32)(dec->num_media_packets)) - 1)))
        {
            g_queue_push_tail(dec->media_packets, gst_buffer_ref(packet));
            g_hash_table_add(dec->media_packet_set, GINT_TO_POINTER(original_seqnum));
            ++dec->num_received_media_packets;
            dec->received_media_packet_mask |= (1ul << (corrected_seqnum - dec->cur_snbase));
            dec->max_packet_size = MAX(dec->max_packet_size, GST_BUFFER_SIZE(packet));

            fec_dec_check_state(dec);
        }
        else
        {
            GST_DEBUG("Received media packet with seqnum %u outside bounds [%u, %u] - pushing aborted", original_seqnum, dec->cur_snbase, dec->cur_snbase + dec->num_media_packets - 1);
        }
    }
    else
    {
        GST_DEBUG("Pushing media packet with seqnum %u, no current snbase set", original_seqnum);
        g_queue_push_tail(dec->media_packets, gst_buffer_ref(packet));
        g_hash_table_add(dec->media_packet_set, GINT_TO_POINTER(original_seqnum));
        ++dec->num_received_media_packets;
    }

    if (dec->num_received_media_packets > dec->num_media_packets)
    {
        guint i;

        GST_DEBUG("Too many media packets in queue - deleting the %u oldest packets", dec->num_received_media_packets - dec->num_media_packets);

        for (i = dec->num_media_packets; i < dec->num_received_media_packets; ++i)
        {
            GstBuffer *media_packet;
            guint16 seqnum;

            media_packet = g_queue_pop_head(dec->media_packets);
            seqnum = gst_rtp_buffer_get_seq(packet);
            g_hash_table_remove(dec->media_packet_set, GINT_TO_POINTER(seqnum));

            gst_buffer_unref(media_packet);
        }

        dec->num_received_media_packets = dec->num_media_packets;
    }
}
Beispiel #19
0
static void
ik_process_events (void)
{
  g_queue_foreach (events_to_process, ik_pair_moves, NULL);

  while (!g_queue_is_empty (events_to_process))
    {
      ik_event_internal_t *event = g_queue_peek_head (events_to_process);
      
      /* This must have been sent as part of a MOVED_TO/MOVED_FROM */
      if (event->sent)
	{
	  /* Pop event */
	  g_queue_pop_head (events_to_process);
	  /* Free the internal event structure */
	  g_free (event);
	  continue;
	}
      
      /* The event isn't ready yet */
      if (!ik_event_ready (event))
	break;
      
      /* Pop it */
      event = g_queue_pop_head (events_to_process);
      
      /* Check if this is a MOVED_FROM that is also sitting in the cookie_hash */
      if (event->event->cookie && event->pair == NULL &&
	  g_hash_table_lookup (cookie_hash, GINT_TO_POINTER (event->event->cookie)))
	g_hash_table_remove (cookie_hash, GINT_TO_POINTER (event->event->cookie));
      
      if (event->pair)
	{
	  /* We send out paired MOVED_FROM/MOVED_TO events in the same event buffer */
	  /* g_assert (event->event->mask == IN_MOVED_FROM && event->pair->event->mask == IN_MOVED_TO); */
	  /* Copy the paired data */
	  event->pair->sent = TRUE;
	  event->sent = TRUE;
	  ik_move_matches++;
	}
      else if (event->event->cookie)
	{
	  /* If we couldn't pair a MOVED_FROM and MOVED_TO together, we change
	   * the event masks */
	  /* Changeing MOVED_FROM to DELETE and MOVED_TO to create lets us make
	   * the gaurantee that you will never see a non-matched MOVE event */
	  
	  if (event->event->mask & IN_MOVED_FROM)
	    {
	      event->event->mask = IN_DELETE|(event->event->mask & IN_ISDIR);
	      ik_move_misses++; /* not super accurate, if we aren't watching the destination it still counts as a miss */
	    }
	  if (event->event->mask & IN_MOVED_TO)
	    event->event->mask = IN_CREATE|(event->event->mask & IN_ISDIR);
	}
      
      /* Push the ik_event_t onto the event queue */
      g_queue_push_tail (event_queue, event->event);
      /* Free the internal event structure */
      g_free (event);
    }
}
Beispiel #20
0
void li_http_headers_free(liHttpHeaders* headers) {
	if (!headers) return;
	g_queue_foreach(&headers->entries, _header_queue_free, NULL);
	g_queue_clear(&headers->entries);
	g_slice_free(liHttpHeaders, headers);
}
Beispiel #21
0
void li_http_headers_reset(liHttpHeaders* headers) {
	g_queue_foreach(&headers->entries, _header_queue_free, NULL);
	g_queue_clear(&headers->entries);
}
Beispiel #22
0
gint
xmms_xform_this_read (xmms_xform_t *xform, gpointer buf, gint siz,
                      xmms_error_t *err)
{
	gint read = 0;
	gint nexths;

	if (xform->error) {
		xmms_error_set (err, XMMS_ERROR_GENERIC, "Read on errored xform");
		return -1;
	}

	/* update hotspots */
	nexths = xmms_xform_hotspots_update (xform);
	if (nexths >= 0) {
		siz = MIN (siz, nexths);
	}

	if (xform->buffered) {
		read = MIN (siz, xform->buffered);
		memcpy (buf, xform->buffer, read);
		xform->buffered -= read;

		/* buffer edited, update hotspot positions */
		g_queue_foreach (xform->hotspots, &xmms_xform_hotspot_callback, &read);

		if (xform->buffered) {
			/* unless we are _peek:ing often
			   this should be fine */
			memmove (xform->buffer, &xform->buffer[read], xform->buffered);
		}
	}

	if (xform->eos) {
		return read;
	}

	while (read < siz) {
		gint res;

		res = xmms_xform_plugin_read (xform->plugin, xform, buf + read, siz - read, err);
		if (xform->metadata_collected && xform->metadata_changed)
			xmms_xform_metadata_update (xform);

		if (res < -1) {
			XMMS_DBG ("Read method of %s returned bad value (%d) - BUG IN PLUGIN", xmms_xform_shortname (xform), res);
			res = -1;
		}

		if (res == 0) {
			xform->eos = TRUE;
			break;
		} else if (res == -1) {
			xform->error = TRUE;
			return -1;
		} else {
			if (read == 0)
				xmms_xform_hotspots_update (xform);

			if (!g_queue_is_empty (xform->hotspots)) {
				if (xform->buffered + res > xform->buffersize) {
					xform->buffersize = MAX (xform->buffersize * 2,
					                         xform->buffersize + res);
					xform->buffer = g_realloc (xform->buffer,
					                           xform->buffersize);
				}

				g_memmove (xform->buffer + xform->buffered, buf + read, res);
				xform->buffered += res;
				break;
			}
			read += res;
		}
	}

	return read;
}
Beispiel #23
0
void
checkcopy_worker (CheckcopyWorkerParams * params)
{
  GQueue *int_q;

  ProgressDialog * progress_dialog;
  CheckcopyPlanner *planner;
  CheckcopyProcessor *proc;
  CheckcopyFileList * list;

  gboolean verify_only;

  verify_only = g_file_has_uri_scheme (params->dest, "verify");

  list = checkcopy_file_list_get_instance ();
  g_object_set (G_OBJECT (list), "verify-only", verify_only, NULL);

  progress_dialog = params->progress_dialog;
  planner = checkcopy_planner_new (progress_dialog);
  proc = checkcopy_processor_new (progress_dialog, params->dest, verify_only);

  int_q = g_queue_new ();

  ext_q = params->queue;

  g_async_queue_ref (ext_q);

  while (TRUE) {
    GFile *file;

    /* Collect everything from the external queue to calculate the size.
     * Since the files are not processed yet, stick them into the internal queue.
     *
     * At this point the internal queue is empty, so we can block once for getting the first item
     * from the external queue
    */
    file = g_async_queue_pop (ext_q);

    progress_dialog_thread_set_status (progress_dialog, PROGRESS_DIALOG_STATUS_CALCULATING_SIZE);

    do {
      g_queue_push_tail (int_q, file);
      checkcopy_traverse (file, CHECKCOPY_FILE_HANDLER (planner));
    } while ((file = g_async_queue_try_pop (ext_q)) != NULL);

#ifdef DEBUG
    {
    gchar *size_str;
    guint64 total_size = 0;

    g_object_get (planner, "total-size", &total_size, NULL);
    size_str = g_format_size_for_display (total_size);

    DBG ("Total size is now %s", size_str);
    g_free (size_str);
    }
#endif

    progress_dialog_thread_set_status (progress_dialog, PROGRESS_DIALOG_STATUS_COPYING);
    g_object_set (G_OBJECT (progress_dialog), "num-files", checkcopy_planner_get_num_files (planner), NULL);

    /* Now process the internal queue */
    while ((file = g_queue_pop_head (int_q)) != NULL) {
      checkcopy_traverse (file, CHECKCOPY_FILE_HANDLER (proc));
      g_object_unref (file);
    }

    checkcopy_file_list_write_checksum (list, params->dest);
    checkcopy_file_list_sweep (list);

    progress_dialog_thread_set_status (progress_dialog, PROGRESS_DIALOG_STATUS_COMPLETED);

#ifdef DEBUG
    progress_dialog_thread_check_stats (progress_dialog);
#endif

    DBG ("Waiting for more things to do");
  }

  /* we won't ever get here but just in case
   * we change the loop condition later */

  g_async_queue_unref (ext_q);
  g_queue_foreach (int_q, (GFunc) g_object_unref, NULL);
  g_queue_free (int_q);

  g_object_unref (planner);
  g_object_unref (proc);
  g_object_unref (list);

  g_object_unref (params->dest);
  g_free (params);
}
Beispiel #24
0
static void stat_srv_on_stats_cb (struct evhttp_request *req, void *ctx)
{
    StatSrv *stat_srv = (StatSrv *) ctx;
    struct evbuffer *evb = NULL;
    gint ref = 0;
    GString *str;
    struct evhttp_uri *uri;
    guint32 total_inodes, file_num, dir_num;
    guint64 read_ops, write_ops, readdir_ops, lookup_ops;
    guint32 cache_entries;
    guint64 total_cache_size, cache_hits, cache_miss;
    struct tm *cur_p;
    struct tm cur;
    time_t now;
    char ts[50];

    uri = evhttp_uri_parse (evhttp_request_get_uri (req));
    LOG_debug (STAT_LOG, "Incoming request: %s from %s:%d", 
        evhttp_request_get_uri (req), req->remote_host, req->remote_port);

    if (uri) {
        const gchar *query;
        
        query = evhttp_uri_get_query (uri);
        if (query) {
            const gchar *refresh = NULL;
            struct evkeyvalq q_params;
            
            TAILQ_INIT (&q_params);
            evhttp_parse_query_str (query, &q_params);
            refresh = http_find_header (&q_params, "refresh");
            if (refresh)
                ref = atoi (refresh);

            evhttp_clear_headers (&q_params);
        }
        evhttp_uri_free (uri);
    }

    str = g_string_new (NULL);
    
    now = time (NULL);
    localtime_r (&now, &cur);
    cur_p = &cur;
    if (!strftime (ts, sizeof (ts), "%H:%M:%S", cur_p))
        ts[0] = '\0';

    g_string_append_printf (str, "RioFS version: %s Uptime: %u sec, Now: %s, Log level: %d, Dir cache time: %u sec<BR>", 
        VERSION, (guint32)(now - stat_srv->boot_time), ts, log_level,
        conf_get_uint (application_get_conf (stat_srv->app), "filesystem.dir_cache_max_time"));

    // DirTree
    dir_tree_get_stats (application_get_dir_tree (stat_srv->app), &total_inodes, &file_num, &dir_num);
    g_string_append_printf (str, "<BR>DirTree: <BR>-Total inodes: %u, Total files: %u, Total directories: %u<BR>",
        total_inodes, file_num, dir_num);

    // Fuse
    rfuse_get_stats (application_get_rfuse (stat_srv->app), &read_ops, &write_ops, &readdir_ops, &lookup_ops);
    g_string_append_printf (str, "<BR>Fuse: <BR>-Read ops: %"G_GUINT64_FORMAT", Write ops: %"G_GUINT64_FORMAT
        ", Readdir ops: %"G_GUINT64_FORMAT", Lookup ops: %"G_GUINT64_FORMAT"<BR>",
        read_ops, write_ops, readdir_ops, lookup_ops);

    // CacheMng
    cache_mng_get_stats (application_get_cache_mng (stat_srv->app), &cache_entries, &total_cache_size, &cache_hits, &cache_miss);
    g_string_append_printf (str, "<BR>CacheMng: <BR>-Total entries: %"G_GUINT32_FORMAT", Total cache size: %"G_GUINT64_FORMAT
        " bytes, Cache hits: %"G_GUINT64_FORMAT", Cache misses: %"G_GUINT64_FORMAT" <BR>", 
        cache_entries, total_cache_size, cache_hits, cache_miss);
    
    g_string_append_printf (str, "<BR>Read workers (%d): <BR>", 
        client_pool_get_client_count (application_get_read_client_pool (stat_srv->app)));
    client_pool_get_client_stats_info (application_get_read_client_pool (stat_srv->app), str, &print_format_http);
    
    g_string_append_printf (str, "<BR>Write workers (%d): <BR>",
        client_pool_get_client_count (application_get_write_client_pool (stat_srv->app)));
    client_pool_get_client_stats_info (application_get_write_client_pool (stat_srv->app), str, &print_format_http);
    
    g_string_append_printf (str, "<BR>Op workers (%d): <BR>",
        client_pool_get_client_count (application_get_ops_client_pool (stat_srv->app)));
    client_pool_get_client_stats_info (application_get_ops_client_pool (stat_srv->app), str, &print_format_http);

    g_string_append_printf (str, "<BR><BR>Operation history (%u max items): <BR>",
        conf_get_uint (application_get_conf (stat_srv->app), "statistics.history_size"));
    g_queue_foreach (stat_srv->q_op_history, (GFunc) stat_srv_print_history_item, str);

    evb = evbuffer_new ();

    evbuffer_add_printf (evb, "<HTTP>");
    if (ref) {
        evbuffer_add_printf (evb, "<HEAD><meta http-equiv=\"refresh\" content=\"%d\"></HEAD>", ref);
    }
    evbuffer_add_printf (evb, "<BODY>");
    evbuffer_add (evb, str->str, str->len);
    evbuffer_add_printf (evb, "</BODY></HTTP>");
    evhttp_send_reply (req, HTTP_OK, "OK", evb);
    evbuffer_free (evb);

    g_string_free (str, TRUE);
}
Beispiel #25
0
void queue_cleanup(void)
{
	g_queue_foreach(queue, queue_free_song, NULL);
	g_queue_free(queue);
}
static GstPadProbeReturn
handle_mq_output (GstPad * pad, GstPadProbeInfo * info, MqStreamCtx * ctx)
{
  GstSplitMuxSink *splitmux = ctx->splitmux;
  MqStreamBuf *buf_info = NULL;

  GST_LOG_OBJECT (pad, "Fired probe type 0x%x\n", info->type);

  /* FIXME: Handle buffer lists, until then make it clear they won't work */
  if (info->type & GST_PAD_PROBE_TYPE_BUFFER_LIST) {
    g_warning ("Buffer list handling not implemented");
    return GST_PAD_PROBE_DROP;
  }
  if (info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
    GstEvent *event = gst_pad_probe_info_get_event (info);

    GST_LOG_OBJECT (pad, "Event %" GST_PTR_FORMAT, event);

    switch (GST_EVENT_TYPE (event)) {
      case GST_EVENT_SEGMENT:
        gst_event_copy_segment (event, &ctx->out_segment);
        break;
      case GST_EVENT_FLUSH_STOP:
        GST_SPLITMUX_LOCK (splitmux);
        gst_segment_init (&ctx->out_segment, GST_FORMAT_UNDEFINED);
        g_queue_foreach (&ctx->queued_bufs, (GFunc) mq_stream_buf_free, NULL);
        g_queue_clear (&ctx->queued_bufs);
        ctx->flushing = FALSE;
        GST_SPLITMUX_UNLOCK (splitmux);
        break;
      case GST_EVENT_FLUSH_START:
        GST_SPLITMUX_LOCK (splitmux);
        GST_LOG_OBJECT (pad, "Flush start");
        ctx->flushing = TRUE;
        GST_SPLITMUX_BROADCAST (splitmux);
        GST_SPLITMUX_UNLOCK (splitmux);
        break;
      case GST_EVENT_EOS:
        GST_SPLITMUX_LOCK (splitmux);
        if (splitmux->state == SPLITMUX_STATE_STOPPED)
          goto beach;
        ctx->out_eos = TRUE;
        GST_SPLITMUX_UNLOCK (splitmux);
        break;
      case GST_EVENT_GAP:{
        GstClockTime gap_ts;

        gst_event_parse_gap (event, &gap_ts, NULL);
        if (gap_ts == GST_CLOCK_TIME_NONE)
          break;

        GST_SPLITMUX_LOCK (splitmux);

        gap_ts = gst_segment_to_running_time (&ctx->out_segment,
            GST_FORMAT_TIME, gap_ts);

        GST_LOG_OBJECT (pad, "Have GAP w/ ts %" GST_TIME_FORMAT,
            GST_TIME_ARGS (gap_ts));

        if (splitmux->state == SPLITMUX_STATE_STOPPED)
          goto beach;
        ctx->out_running_time = gap_ts;
        complete_or_wait_on_out (splitmux, ctx);
        GST_SPLITMUX_UNLOCK (splitmux);
        break;
      }
      default:
        break;
    }
    return GST_PAD_PROBE_PASS;
  }

  /* Allow everything through until the configured next stopping point */
  GST_SPLITMUX_LOCK (splitmux);

  buf_info = g_queue_pop_tail (&ctx->queued_bufs);
  if (buf_info == NULL)
    /* Can only happen due to a poorly timed flush */
    goto beach;

  /* If we have popped a keyframe, decrement the queued_gop count */
  if (buf_info->keyframe && splitmux->queued_gops > 0)
    splitmux->queued_gops--;

  ctx->out_running_time = buf_info->run_ts;

  GST_LOG_OBJECT (splitmux,
      "Pad %" GST_PTR_FORMAT " buffer with TS %" GST_TIME_FORMAT
      " size %" G_GSIZE_FORMAT,
      pad, GST_TIME_ARGS (ctx->out_running_time), buf_info->buf_size);

  complete_or_wait_on_out (splitmux, ctx);

  if (splitmux->muxed_out_time == GST_CLOCK_TIME_NONE ||
      splitmux->muxed_out_time < buf_info->run_ts)
    splitmux->muxed_out_time = buf_info->run_ts;

  splitmux->muxed_out_bytes += buf_info->buf_size;

#ifndef GST_DISABLE_GST_DEBUG
  {
    GstBuffer *buf = gst_pad_probe_info_get_buffer (info);
    GST_LOG_OBJECT (pad, "Returning to pass buffer %" GST_PTR_FORMAT
        " run ts %" GST_TIME_FORMAT, buf,
        GST_TIME_ARGS (ctx->out_running_time));
  }
#endif

  GST_SPLITMUX_UNLOCK (splitmux);

  mq_stream_buf_free (buf_info);

  return GST_PAD_PROBE_PASS;

beach:
  GST_SPLITMUX_UNLOCK (splitmux);
  return GST_PAD_PROBE_DROP;
}
Beispiel #27
0
void fec_dec_flush_recovered_packets(fec_dec *dec)
{
    g_queue_foreach(dec->recovered_packets, fec_dec_clear_packet, NULL);
    g_queue_clear(dec->recovered_packets);
}
static void
photos_item_manager_collection_path_free (PhotosItemManager *self)
{
  g_queue_foreach (self->collection_path, photos_item_manager_collection_path_free_foreach, NULL);
  g_queue_free (self->collection_path);
}
Beispiel #29
0
static gpointer
brasero_dvdcss_write_image_thread (gpointer data)
{
	guchar buf [DVDCSS_BLOCK_SIZE * BRASERO_DVDCSS_I_BLOCKS];
	BraseroScrambledSectorRange *range = NULL;
	BraseroMedium *medium = NULL;
	BraseroVolFile *files = NULL;
	dvdcss_handle *handle = NULL;
	BraseroDrive *drive = NULL;
	BraseroDvdcssPrivate *priv;
	gint64 written_sectors = 0;
	BraseroDvdcss *self = data;
	BraseroTrack *track = NULL;
	guint64 remaining_sectors;
	FILE *output_fd = NULL;
	BraseroVolSrc *vol;
	gint64 volume_size;
	GQueue *map = NULL;

	brasero_job_set_use_average_rate (BRASERO_JOB (self), TRUE);
	brasero_job_set_current_action (BRASERO_JOB (self),
					BRASERO_BURN_ACTION_ANALYSING,
					_("Retrieving DVD keys"),
					FALSE);
	brasero_job_start_progress (BRASERO_JOB (self), FALSE);

	priv = BRASERO_DVDCSS_PRIVATE (self);

	/* get the contents of the DVD */
	brasero_job_get_current_track (BRASERO_JOB (self), &track);
	drive = brasero_track_disc_get_drive (BRASERO_TRACK_DISC (track));

	vol = brasero_volume_source_open_file (brasero_drive_get_device (drive), &priv->error);
	files = brasero_volume_get_files (vol,
					  0,
					  NULL,
					  NULL,
					  NULL,
					  &priv->error);
	brasero_volume_source_close (vol);
	if (!files)
		goto end;

	medium = brasero_drive_get_medium (drive);
	brasero_medium_get_data_size (medium, NULL, &volume_size);
	if (volume_size == -1) {
		priv->error = g_error_new (BRASERO_BURN_ERROR,
					   BRASERO_BURN_ERROR_GENERAL,
					   _("The size of the volume could not be retrieved"));
		goto end;
	}

	/* create a handle/open DVD */
	handle = dvdcss_open (brasero_drive_get_device (drive));
	if (!handle) {
		priv->error = g_error_new (BRASERO_BURN_ERROR,
					   BRASERO_BURN_ERROR_GENERAL,
					   _("Video DVD could not be opened"));
		goto end;
	}

	/* look through the files to get the ranges of encrypted sectors
	 * and cache the CSS keys while at it. */
	map = g_queue_new ();
	if (!brasero_dvdcss_create_scrambled_sectors_map (self, drive, map, handle, files, &priv->error))
		goto end;

	BRASERO_JOB_LOG (self, "DVD map created (keys retrieved)");

	g_queue_sort (map, brasero_dvdcss_sort_ranges, NULL);

	brasero_volume_file_free (files);
	files = NULL;

	if (dvdcss_seek (handle, 0, DVDCSS_NOFLAGS) < 0) {
		BRASERO_JOB_LOG (self, "Error initial seeking");
		priv->error = g_error_new (BRASERO_BURN_ERROR,
					   BRASERO_BURN_ERROR_GENERAL,
					   _("Error while reading video DVD (%s)"),
					   dvdcss_error (handle));
		goto end;
	}

	brasero_job_set_current_action (BRASERO_JOB (self),
					BRASERO_BURN_ACTION_DRIVE_COPY,
					_("Copying video DVD"),
					FALSE);

	brasero_job_start_progress (BRASERO_JOB (self), TRUE);

	remaining_sectors = volume_size;
	range = g_queue_pop_head (map);

	if (brasero_job_get_fd_out (BRASERO_JOB (self), NULL) != BRASERO_BURN_OK) {
		gchar *output = NULL;

		brasero_job_get_image_output (BRASERO_JOB (self), &output, NULL);
		output_fd = fopen (output, "w");
		if (!output_fd) {
			priv->error = g_error_new_literal (BRASERO_BURN_ERROR,
							   BRASERO_BURN_ERROR_GENERAL,
							   g_strerror (errno));
			g_free (output);
			goto end;
		}
		g_free (output);
	}

	while (remaining_sectors) {
		gint flag;
		guint64 num_blocks, data_size;

		if (priv->cancel)
			break;

		num_blocks = BRASERO_DVDCSS_I_BLOCKS;

		/* see if we are approaching the end of the dvd */
		if (num_blocks > remaining_sectors)
			num_blocks = remaining_sectors;

		/* see if we need to update the key */
		if (!range || written_sectors < range->start) {
			/* this is in a non scrambled sectors range */
			flag = DVDCSS_NOFLAGS;
	
			/* we don't want to mix scrambled and non scrambled sectors */
			if (range && written_sectors + num_blocks > range->start)
				num_blocks = range->start - written_sectors;
		}
		else {
			/* this is in a scrambled sectors range */
			flag = DVDCSS_READ_DECRYPT;

			/* see if we need to update the key */
			if (written_sectors == range->start) {
				int pos;

				pos = dvdcss_seek (handle, written_sectors, DVDCSS_SEEK_KEY);
				if (pos < 0) {
					BRASERO_JOB_LOG (self, "Error seeking");
					priv->error = g_error_new (BRASERO_BURN_ERROR,
								   BRASERO_BURN_ERROR_GENERAL,
								   _("Error while reading video DVD (%s)"),
								   dvdcss_error (handle));
					break;
				}
			}

			/* we don't want to mix scrambled and non scrambled sectors
			 * NOTE: range->end address is the next non scrambled sector */
			if (written_sectors + num_blocks > range->end)
				num_blocks = range->end - written_sectors;

			if (written_sectors + num_blocks == range->end) {
				/* update to get the next range of scrambled sectors */
				g_free (range);
				range = g_queue_pop_head (map);
			}
		}

		num_blocks = dvdcss_read (handle, buf, num_blocks, flag);
		if (num_blocks < 0) {
			BRASERO_JOB_LOG (self, "Error reading");
			priv->error = g_error_new (BRASERO_BURN_ERROR,
						   BRASERO_BURN_ERROR_GENERAL,
						   _("Error while reading video DVD (%s)"),
						   dvdcss_error (handle));
			break;
		}

		data_size = num_blocks * DVDCSS_BLOCK_SIZE;
		if (output_fd) {
			if (fwrite (buf, 1, data_size, output_fd) != data_size) {
                                int errsv = errno;

				priv->error = g_error_new (BRASERO_BURN_ERROR,
							   BRASERO_BURN_ERROR_GENERAL,
							   _("Data could not be written (%s)"),
							   g_strerror (errsv));
				break;
			}
		}
		else {
			BraseroBurnResult result;

			result = brasero_dvdcss_write_sector_to_fd (self,
								    buf,
								    data_size);
			if (result != BRASERO_BURN_OK)
				break;
		}

		written_sectors += num_blocks;
		remaining_sectors -= num_blocks;
		brasero_job_set_written_track (BRASERO_JOB (self), written_sectors * DVDCSS_BLOCK_SIZE);
	}

end:

	if (range)
		g_free (range);

	if (handle)
		dvdcss_close (handle);

	if (files)
		brasero_volume_file_free (files);

	if (output_fd)
		fclose (output_fd);

	if (map) {
		g_queue_foreach (map, (GFunc) g_free, NULL);
		g_queue_free (map);
	}

	if (!priv->cancel)
		priv->thread_id = g_idle_add (brasero_dvdcss_thread_finished, self);

	/* End thread */
	g_mutex_lock (priv->mutex);
	priv->thread = NULL;
	g_cond_signal (priv->cond);
	g_mutex_unlock (priv->mutex);

	g_thread_exit (NULL);

	return NULL;
}
Beispiel #30
0
static void rm_tm_extract(RmTreeMerger *self) {
    /* Iterate over all directories per hash (which are same therefore) */
    GList *result_table_values = g_hash_table_get_values(self->result_table);
    result_table_values =
        g_list_sort(result_table_values, (GCompareFunc)rm_tm_cmp_directory_groups);

    for(GList *iter = result_table_values; iter; iter = iter->next) {
        /* Needs at least two directories to be duplicate... */
        GQueue *dir_list = iter->data;

#ifdef _RM_TREEMERGE_DEBUG
        for(GList *i = dir_list->head; i; i = i->next) {
            RmDirectory *d = i->data;
            char buf[512];
            memset(buf, 0, sizeof(buf));
            rm_digest_hexstring(d->digest, buf);
            g_printerr("    mergeups=%" LLU ": %s - %s\n", d->mergeups, d->dirname, buf);
        }
        g_printerr("---\n");
#endif
        if(dir_list->length < 2) {
            continue;
        }

        if(rm_session_was_aborted(self->session)) {
            break;
        }

        /* List of result directories */
        GQueue result_dirs = G_QUEUE_INIT;

        /* Sort the RmDirectory list by their path depth, lowest depth first */
        g_queue_sort(dir_list, (GCompareDataFunc)rm_tm_sort_paths, self);

        /* Output the directories and mark their children to prevent
         * duplicate directory reports in lower levels.
         */
        for(GList *iter = dir_list->head; iter; iter = iter->next) {
            RmDirectory *directory = iter->data;
            if(directory->finished == false) {
                rm_tm_mark_finished(self, directory);
                g_queue_push_head(&result_dirs, directory);
            }
        }

        /* Make sure the original directory lands as first
         * in the result_dirs queue.
         */
        g_queue_sort(&result_dirs, (GCompareDataFunc)rm_tm_sort_orig_criteria, self);

        GQueue file_adaptor_group = G_QUEUE_INIT;

        for(GList *iter = result_dirs.head; iter; iter = iter->next) {
            RmDirectory *directory = iter->data;
            RmFile *mask = rm_directory_as_file(self, directory);
            g_queue_push_tail(&file_adaptor_group, mask);

            if(iter == result_dirs.head) {
                /* First one in the group -> It's the original */
                mask->is_original = true;
                rm_tm_mark_original_files(self, directory);
            } else {
                if(rm_tm_mark_duplicate_files(self, directory, 0) ==
                   directory->dupe_count) {
                    /* Mark the file as original when all files in it are preferred. */
                    mask->is_original = true;
                    rm_tm_mark_original_files(self, directory);
                }
            }

            if(self->session->cfg->write_unfinished) {
                rm_tm_write_unfinished_cksums(self, directory);
            }
        }

        if(result_dirs.length >= 2) {
            rm_shred_forward_to_output(self->session, &file_adaptor_group);
        }

        g_queue_foreach(&file_adaptor_group, (GFunc)g_free, NULL);
        g_queue_clear(&file_adaptor_group);
        g_queue_clear(&result_dirs);
    }

    g_list_free(result_table_values);

    /* Iterate over all non-finished dirs in the tree,
     * and grab unfinished files that must be dupes elsewhise.
     */
    rm_trie_iter(&self->dir_tree, NULL, true, false, rm_tm_iter_unfinished_files, self);

    /* Now here's a problem. Consider an input like this:
     *  /root
     *  ├── a
     *  ├── sub1
     *  │   ├── a
     *  │   └── b
     *  └── sub2
     *      ├── a
     *      └── b
     *
     *  This yields two duplicate dirs (sub1, sub2)
     *  and one duplicate, unmatched file (a).
     *
     *  For outputting files we need groups, which consist of at least 2 files.
     *  So how to group that, so we don't end up deleting a file many times?
     *  We always choose which directories are originals first, so we flag all
     *  files in it as originals.
     */
    GHashTableIter iter;
    g_hash_table_iter_init(&iter, self->file_groups);

    GQueue *file_list = NULL;
    while(g_hash_table_iter_next(&iter, NULL, (void **)&file_list)) {
        bool has_one_dupe = false;
        RmOff file_size_acc = 0;

        GList *next = NULL;
        for(GList *iter = file_list->head; iter; iter = next) {
            RmFile *file = iter->data;
            next = iter->next;

            bool is_duplicate = g_hash_table_contains(self->file_checks, file->digest);
            has_one_dupe |= is_duplicate;

            /* with --partial-hidden we do not want to output */
            if(self->session->cfg->partial_hidden && file->is_hidden) {
                g_queue_delete_link(file_list, iter);
                continue;
            }

            if(iter != file_list->head && !is_duplicate) {
                file_size_acc += file->file_size;
            }
        }

        if(file_list->length >= 2) {
            /* If no separate duplicate files are requested, we can stop here */
            if(self->session->cfg->find_duplicates == false) {
                self->session->total_lint_size -= file_size_acc;
                self->session->dup_group_counter -= 1;
                self->session->dup_counter -= file_list->length - 1;
            } else {
                rm_shred_group_find_original(self->session, file_list);
                rm_shred_forward_to_output(self->session, file_list);
            }
        }
    }
}