<commit_before>/*  XMMS2 - X Music Multiplexer System
 *  Copyright (C) 2003	<NAME>, <NAME>, <NAME>
 * 
 *  PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
 * 
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *                   
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 */




/** @file This file controls the mediainfothread.
  *
  */

#include "xmms/xmms.h"
#include "xmms/transport.h"
#include "xmms/decoder.h"
#include "xmms/util.h"
#include "xmms/playlist.h"
#include "xmms/mediainfo.h"
#include "xmms/medialib.h"
#include "xmms/plsplugins.h"
#include "xmms/signal_xmms.h"

#include "internal/transport_int.h"
#include "internal/decoder_int.h"

#include <glib.h>

/** @file Control for the mediainfo thread */

/** @defgroup MediaInfoThread MediaInfoThread
  * @ingroup XMMSServer
  * @brief The mediainfo thread.
  *
  * When a item is added to the playlist the mediainfo thread will
  * start extracting the information from this entry and update it
  * if additional information is found.
  * @{
  */

struct xmms_mediainfo_thread_St {
	GThread *thread;
	GMutex *mutex;
	GCond *cond;

	gboolean running;
	GQueue *queue;
	xmms_playlist_t *playlist;
};

static gpointer xmms_mediainfo_thread_thread (gpointer data);
static void xmms_mediainfo_playlist_changed_cb (xmms_object_t *object, gconstpointer arg, gpointer userdata);


/**
  * Start a new mediainfo thread
  */

xmms_mediainfo_thread_t *
xmms_mediainfo_thread_start (xmms_playlist_t *playlist)
{
	xmms_mediainfo_thread_t *mtt;

	g_return_val_if_fail (playlist, NULL);

	mtt = g_new0 (xmms_mediainfo_thread_t, 1);

	mtt->mutex = g_mutex_new ();
	mtt->cond = g_cond_new ();
	mtt->playlist = playlist;
	mtt->queue = g_queue_new ();
	mtt->running = TRUE;
	mtt->thread = g_thread_create (xmms_mediainfo_thread_thread, mtt, FALSE, NULL);

	xmms_object_connect (XMMS_OBJECT (playlist), XMMS_SIGNAL_PLAYLIST_CHANGED, xmms_mediainfo_playlist_changed_cb, mtt);
	

	return mtt;
}

/**
  * Kill the mediainfo thread
  */

void
xmms_mediainfo_thread_stop (xmms_mediainfo_thread_t *mit)
{
	g_mutex_lock (mit->mutex);

	while (g_queue_pop_head (mit->queue))
		;
	mit->running = FALSE;
	g_cond_signal (mit->cond);

	g_mutex_unlock (mit->mutex);

	g_thread_join (mit->thread);

	g_queue_free (mit->queue);
}

/** @} */

static void
xmms_mediainfo_playlist_changed_cb (xmms_object_t *object, gconstpointer arg, gpointer userdata)
{
	xmms_mediainfo_thread_t *mit = userdata;
	const xmms_object_method_arg_t *oarg = arg;
	xmms_playlist_changed_msg_t *chmsg = oarg->retval.plch;

	if (chmsg->type == XMMS_PLAYLIST_CHANGED_ADD) {
		g_mutex_lock (mit->mutex);

		g_queue_push_tail (mit->queue, GUINT_TO_POINTER (chmsg->id));

		g_cond_signal (mit->cond);

		g_mutex_unlock (mit->mutex);
	}
}

static gpointer
xmms_mediainfo_thread_thread (gpointer data)
{
	xmms_mediainfo_thread_t *mtt = (xmms_mediainfo_thread_t *) data;

	g_mutex_lock (mtt->mutex);

	while (mtt->running) {
		xmms_playlist_entry_t *entry;
		guint id;
		

		XMMS_DBG ("MediainfoThread is idle.");
		g_cond_wait (mtt->cond, mtt->mutex);

		XMMS_DBG ("MediainfoThread is awake!");

		while ((id = GPOINTER_TO_UINT (g_queue_pop_head (mtt->queue)))) {
			xmms_transport_t *transport;
			xmms_playlist_plugin_t *plsplugin;
			xmms_decoder_t *decoder;
			xmms_error_t err;
			const gchar *mime;

			xmms_error_reset (&err);

			g_mutex_unlock (mtt->mutex);

			entry = xmms_playlist_get_byid (mtt->playlist, id, &err);

			/* Check if this is in the medialib first.*/
			if (xmms_medialib_entry_get (entry)) {
				xmms_playlist_entry_changed (mtt->playlist, entry);
				xmms_object_unref (entry);
				continue;
			}

			XMMS_DBG ("Entry is : %s", xmms_playlist_entry_url_get (entry));

			transport = xmms_transport_new ();
			xmms_transport_open (transport, entry);
			if (!transport) {
				xmms_object_unref (entry);
				continue;
			}

			if (!xmms_transport_islocal (transport))
				continue;

			mime = xmms_transport_mimetype_get (transport);

			if (!mime) {
				xmms_object_unref (entry);
				xmms_object_unref (transport);
				continue;
			}

			plsplugin = xmms_playlist_plugin_new (mime);
			if (plsplugin) {

				/* This is a playlist file... */<commit_msg>applied patch for a segfault fix from tilman.<commit_after>/*  XMMS2 - X Music Multiplexer System
 *  Copyright (C) 2003	<NAME>, <NAME>, <NAME>
 * 
 *  PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
 * 
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *                   
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 */




/** @file This file controls the mediainfothread.
  *
  */

#include "xmms/xmms.h"
#include "xmms/transport.h"
#include "xmms/decoder.h"
#include "xmms/util.h"
#include "xmms/playlist.h"
#include "xmms/mediainfo.h"
#include "xmms/medialib.h"
#include "xmms/plsplugins.h"
#include "xmms/signal_xmms.h"

#include "internal/transport_int.h"
#include "internal/decoder_int.h"

#include <glib.h>

/** @file Control for the mediainfo thread */

/** @defgroup MediaInfoThread MediaInfoThread
  * @ingroup XMMSServer
  * @brief The mediainfo thread.
  *
  * When a item is added to the playlist the mediainfo thread will
  * start extracting the information from this entry and update it
  * if additional information is found.
  * @{
  */

struct xmms_mediainfo_thread_St {
	GThread *thread;
	GMutex *mutex;
	GCond *cond;

	gboolean running;
	GQueue *queue;
	xmms_playlist_t *playlist;
};

static gpointer xmms_mediainfo_thread_thread (gpointer data);
static void xmms_mediainfo_playlist_changed_cb (xmms_object_t *object, gconstpointer arg, gpointer userdata);


/**
  * Start a new mediainfo thread
  */

xmms_mediainfo_thread_t *
xmms_mediainfo_thread_start (xmms_playlist_t *playlist)
{
	xmms_mediainfo_thread_t *mtt;

	g_return_val_if_fail (playlist, NULL);

	mtt = g_new0 (xmms_mediainfo_thread_t, 1);

	mtt->mutex = g_mutex_new ();
	mtt->cond = g_cond_new ();
	mtt->playlist = playlist;
	mtt->queue = g_queue_new ();
	mtt->running = TRUE;
	mtt->thread = g_thread_create (xmms_mediainfo_thread_thread, mtt, FALSE, NULL);

	xmms_object_connect (XMMS_OBJECT (playlist), XMMS_SIGNAL_PLAYLIST_CHANGED, xmms_mediainfo_playlist_changed_cb, mtt);
	

	return mtt;
}

/**
  * Kill the mediainfo thread
  */

void
xmms_mediainfo_thread_stop (xmms_mediainfo_thread_t *mit)
{
	g_mutex_lock (mit->mutex);

	while (g_queue_pop_head (mit->queue))
		;
	mit->running = FALSE;
	g_cond_signal (mit->cond);

	g_mutex_unlock (mit->mutex);

	g_thread_join (mit->thread);

	g_queue_free (mit->queue);
}

/** @} */

static void
xmms_mediainfo_playlist_changed_cb (xmms_object_t *object, gconstpointer arg, gpointer userdata)
{
	xmms_mediainfo_thread_t *mit = userdata;
	const xmms_object_method_arg_t *oarg = arg;
	xmms_playlist_changed_msg_t *chmsg = oarg->retval.plch;

	if (chmsg->type == XMMS_PLAYLIST_CHANGED_ADD) {
		g_mutex_lock (mit->mutex);

		g_queue_push_tail (mit->queue, GUINT_TO_POINTER (chmsg->id));

		g_cond_signal (mit->cond);

		g_mutex_unlock (mit->mutex);
	}
}

static gpointer
xmms_mediainfo_thread_thread (gpointer data)
{
	xmms_mediainfo_thread_t *mtt = (xmms_mediainfo_thread_t *) data;

	g_mutex_lock (mtt->mutex);

	while (mtt->running) {
		xmms_playlist_entry_t *entry;
		guint id;
		

		XMMS_DBG ("MediainfoThread is idle.");
		g_cond_wait (mtt->cond, mtt->mutex);

		XMMS_DBG ("MediainfoThread is awake!");

		while ((id = GPOINTER_TO_UINT (g_queue_pop_head (mtt->queue)))) {
			xmms_transport_t *transport;
			xmms_playlist_plugin_t *plsplugin;
			xmms_decoder_t *decoder;
			xmms_error_t err;
			const gchar *mime;

			xmms_error_reset (&err);

			g_mutex_unlock (mtt->mutex);

			entry = xmms_playlist_get_byid (mtt->playlist, id, &err);

			/* Check if this is in the medialib first.*/
			if (xmms_medialib_entry_get (entry)) {
				xmms_playlist_entry_changed (mtt->playlist, entry);
				xmms_object_unref (entry);
				continue;
			}

			XMMS_DBG ("Entry is : %s", xmms_playlist_entry_url_get (entry));

			transport = xmms_transport_new ();
			if (!transport || !xmms_transport_open (transport, entry)) {
				xmms_object_unref (entry);
				continue;
			}

			if (!xmms_transport_islocal (transport))
				continue;

			mime = xmms_transport_mimetype_get (transport);

			if (!mime) {
				xmms_object_unref (entry);
				xmms_object_unref (transport);
				continue;
			}

			plsplugin = xmms_playlist_plugin_new (mime);
			if (plsplugin) {

				/* This is a playlist file... */
{'fraction_non_alphanumeric': 0.10819282317336792, 'fraction_numerical': 0.0019455252918287938, 'mean_word_length': 4.302578796561605, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '194904', 'n_tokens_mistral': 3813, 'n_tokens_neox': 3520, 'n_words': 823}