1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Massimo Cora' 2008 <maxcvs@email.it>
6 * anjuta_trunk is free software.
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
13 * anjuta_trunk is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with anjuta_trunk. If not, write to:
20 * The Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA.
26 #include "symbol-db-system.h"
30 #include <glib/gstdio.h>
31 #include <libanjuta/anjuta-debug.h>
32 #include <libanjuta/anjuta-launcher.h>
33 #include <libanjuta/interfaces/ianjuta-language.h>
36 struct _SymbolDBSystemPriv
38 AnjutaLauncher
*single_package_scan_launcher
;
39 IAnjutaLanguage
*lang_manager
;
40 SymbolDBEngine
*sdbe_globals
;
46 typedef struct _SingleScanData
{
52 PackageParseableCallback parseable_cb
;
53 gpointer parseable_data
;
57 typedef struct _EngineScanData
{
61 gboolean special_abort_scan
;
62 GPtrArray
*files_to_scan_array
;
63 GPtrArray
*languages_array
;
75 static unsigned int signals
[LAST_SIGNAL
] = { 0 };
77 G_DEFINE_TYPE (SymbolDBSystem
, sdb_system
, G_TYPE_OBJECT
);
81 on_pkg_config_exit (AnjutaLauncher
* launcher
, int child_pid
,
82 int exit_status
, gulong time_taken_in_seconds
,
86 on_engine_package_scan_end (SymbolDBEngine
*dbe
, gint process_id
, gpointer user_data
);
89 destroy_single_scan_data (SingleScanData
*ss_data
)
91 g_return_if_fail (ss_data
!= NULL
);
93 g_free (ss_data
->package_name
);
94 g_free (ss_data
->contents
);
100 destroy_engine_scan_data (EngineScanData
*es_data
)
104 g_list_foreach (es_data
->cflags
, (GFunc
)g_free
, NULL
);
105 g_list_free (es_data
->cflags
);
108 g_free (es_data
->package_name
);
110 if (es_data
->special_abort_scan
== TRUE
)
112 g_ptr_array_foreach (es_data
->files_to_scan_array
, (GFunc
)g_free
, NULL
);
113 g_ptr_array_free (es_data
->files_to_scan_array
, TRUE
);
115 g_ptr_array_foreach (es_data
->languages_array
, (GFunc
)g_free
, NULL
);
116 g_ptr_array_free (es_data
->languages_array
, TRUE
);
122 on_engine_package_single_file_scan_end (SymbolDBEngine
*dbe
, gpointer user_data
)
124 SymbolDBSystem
*sdbs
;
126 sdbs
= SYMBOL_DB_SYSTEM (user_data
);
128 g_signal_emit (sdbs
, signals
[SINGLE_FILE_SCAN_END
], 0);
132 sdb_system_init (SymbolDBSystem
*object
)
134 SymbolDBSystem
*sdbs
;
136 sdbs
= SYMBOL_DB_SYSTEM (object
);
137 sdbs
->priv
= g_new0 (SymbolDBSystemPriv
, 1);
139 /* create launcher for single global package scan */
140 sdbs
->priv
->single_package_scan_launcher
= anjuta_launcher_new ();
141 anjuta_launcher_set_check_passwd_prompt (sdbs
->priv
->single_package_scan_launcher
,
144 /* single scan launcher's queue */
145 sdbs
->priv
->sscan_queue
= g_queue_new ();
146 sdbs
->priv
->engine_queue
= g_queue_new ();
151 sdb_system_finalize (GObject
*object
)
153 SymbolDBSystem
*sdbs
;
154 SymbolDBSystemPriv
*priv
;
156 sdbs
= SYMBOL_DB_SYSTEM (object
);
159 /* disconnect all signals */
160 g_signal_handlers_disconnect_by_func (G_OBJECT (priv
->sdbe_globals
),
161 on_engine_package_single_file_scan_end
,
163 g_signal_handlers_disconnect_matched (G_OBJECT (priv
->sdbe_globals
),
168 on_engine_package_scan_end
,
171 if (priv
->single_package_scan_launcher
)
173 anjuta_launcher_reset (priv
->single_package_scan_launcher
);
174 g_object_unref (priv
->single_package_scan_launcher
);
175 priv
->single_package_scan_launcher
= NULL
;
178 /* free also the queue */
179 g_queue_foreach (priv
->sscan_queue
, (GFunc
)g_free
, NULL
);
180 g_queue_free (priv
->sscan_queue
);
181 priv
->sscan_queue
= NULL
;
183 /* free engine queue */
184 g_queue_foreach (priv
->engine_queue
, (GFunc
)destroy_engine_scan_data
, NULL
);
185 g_queue_free (priv
->engine_queue
);
186 priv
->engine_queue
= NULL
;
188 G_OBJECT_CLASS (sdb_system_parent_class
)->finalize (object
);
192 sdb_system_class_init (SymbolDBSystemClass
*klass
)
194 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
196 signals
[SCAN_PACKAGE_START
]
197 = g_signal_new ("scan-package-start",
198 G_OBJECT_CLASS_TYPE (object_class
),
200 G_STRUCT_OFFSET (SymbolDBSystemClass
, scan_package_start
),
202 g_cclosure_marshal_VOID__UINT_POINTER
, G_TYPE_NONE
,
207 signals
[SCAN_PACKAGE_END
]
208 = g_signal_new ("scan-package-end",
209 G_OBJECT_CLASS_TYPE (object_class
),
211 G_STRUCT_OFFSET (SymbolDBSystemClass
, scan_package_end
),
213 g_cclosure_marshal_VOID__STRING
, G_TYPE_NONE
,
217 signals
[SINGLE_FILE_SCAN_END
]
218 = g_signal_new ("single-file-scan-end",
219 G_OBJECT_CLASS_TYPE (object_class
),
221 G_STRUCT_OFFSET (SymbolDBSystemClass
, single_file_scan_end
),
223 g_cclosure_marshal_VOID__VOID
, G_TYPE_NONE
, 0);
225 object_class
->finalize
= sdb_system_finalize
;
229 * @return GList of cflags (strings) in a format like /usr/include/my_foo_lib.
230 * @return NULL on error.
233 sdb_system_get_normalized_cflags (const gchar
*chars
)
238 const gchar
*curr_flag
;
240 /* We should receive here something like
241 * '-I/usr/include/gimp-2.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include'.
242 * Split up the chars and take a decision if we like it or not.
244 flags
= g_strsplit (chars
, " ", -1);
247 /* if, after the while loop, good_flags is != NULL that means that we found
248 * some good flags to include for a future scan
251 while ((curr_flag
= flags
[i
++]) != NULL
)
253 /* '-I/usr/include/gimp-2.0' would be good, but '/usr/include/' wouldn't. */
254 if (g_regex_match_simple ("\\.*/include/\\w+", curr_flag
, 0, 0) == TRUE
)
256 /* FIXME the +2. It's to skip the -I */
257 DEBUG_PRINT ("adding %s to good_flags", curr_flag
+2);
258 /* FIXME the +2. It's to skip the -I */
259 good_flags
= g_list_prepend (good_flags
, g_strdup (curr_flag
+ 2));
269 symbol_db_system_new (SymbolDBPlugin
*sdb_plugin
,
270 const SymbolDBEngine
*sdbe
)
272 SymbolDBSystem
*sdbs
;
273 SymbolDBSystemPriv
*priv
;
275 g_return_val_if_fail (sdbe
!= NULL
, NULL
);
276 sdbs
= g_object_new (SYMBOL_TYPE_DB_SYSTEM
, NULL
);
279 priv
->sdbe_globals
= (SymbolDBEngine
*)sdbe
;
281 priv
->lang_manager
= anjuta_shell_get_interface (ANJUTA_PLUGIN(sdb_plugin
)->shell
,
282 IAnjutaLanguage
, NULL
);
284 g_signal_connect (G_OBJECT (priv
->sdbe_globals
), "single-file-scan-end",
285 G_CALLBACK (on_engine_package_single_file_scan_end
), sdbs
);
291 * Check on globals db if the project 'package_name' is present or not.
294 symbol_db_system_is_package_parsed (SymbolDBSystem
*sdbs
,
295 const gchar
* package_name
,
296 const gchar
* package_version
)
298 SymbolDBSystemPriv
*priv
;
300 g_return_val_if_fail (sdbs
!= NULL
, FALSE
);
301 g_return_val_if_fail (package_name
!= NULL
, FALSE
);
305 return symbol_db_engine_project_exists (priv
->sdbe_globals
,
306 package_name
, package_version
);
310 on_pkg_config_output (AnjutaLauncher
* launcher
,
311 AnjutaLauncherOutputType output_type
,
312 const gchar
* chars
, gpointer user_data
)
314 SingleScanData
*ss_data
;
316 if (output_type
== ANJUTA_LAUNCHER_OUTPUT_STDERR
)
318 /* no way. We don't like errors on stderr... */
322 ss_data
= (SingleScanData
*)user_data
;
324 if (ss_data
->contents
!= NULL
)
327 to_be_freed
= ss_data
->contents
;
329 /* concatenate the output to the relative package's object */
330 ss_data
->contents
= g_strconcat (ss_data
->contents
, chars
, NULL
);
331 g_free (to_be_freed
);
335 ss_data
->contents
= g_strdup (chars
);
340 sdb_system_files_visit_dir (GList
**files_list
, GFile
*file
)
342 GFileEnumerator
*enumerator
;
344 if ((enumerator
= g_file_enumerate_children (file
, "standard::name,standard::type",
345 G_FILE_QUERY_INFO_NONE
, NULL
, NULL
)))
349 info
= g_file_enumerator_next_file (enumerator
, NULL
, NULL
);
355 type
= g_file_info_get_file_type (info
);
356 child_file
= g_file_resolve_relative_path (file
, g_file_info_get_name (info
));
358 if (type
== G_FILE_TYPE_DIRECTORY
)
361 files_list
= sdb_system_files_visit_dir (files_list
, child_file
);
363 g_object_unref (child_file
);
366 *files_list
= g_list_prepend (*files_list
, child_file
);
368 g_object_unref (info
);
370 info
= g_file_enumerator_next_file (enumerator
, NULL
, NULL
);
373 g_object_unref (enumerator
);
380 prepare_files_to_be_scanned (SymbolDBSystem
*sdbs
,
382 GPtrArray
*OUT_files_to_scan_array
,
383 GPtrArray
*OUT_languages_array
)
385 SymbolDBSystemPriv
*priv
;
393 GList
*files_tmp_list
= NULL
;
397 file
= g_file_new_for_path ((gchar
*)node
->data
);
399 /* files_tmp_list needs to be freed */
400 sdb_system_files_visit_dir (&files_tmp_list
, file
);
401 g_object_unref (file
);
403 if (files_tmp_list
!= NULL
)
405 /* last loop here. With files_visit_dir we'll retrieve all files nodes
406 * under the passed directory
409 tmp_node
= files_tmp_list
;
413 if ((info
= g_file_query_info ((GFile
*)tmp_node
->data
, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE
,
414 G_FILE_QUERY_INFO_NONE
, NULL
, NULL
)))
416 IAnjutaLanguageId lang_id
;
419 lang_id
= ianjuta_language_get_from_mime_type (priv
->lang_manager
,
420 g_file_info_get_content_type (info
),
423 g_object_unref (info
);
425 /* No supported language... */
431 lang
= ianjuta_language_get_name (priv
->lang_manager
, lang_id
, NULL
);
433 g_ptr_array_add (OUT_languages_array
, g_strdup (lang
));
434 g_ptr_array_add (OUT_files_to_scan_array
,
435 g_file_get_path ((GFile
*)tmp_node
->data
));
437 } while ((tmp_node
= tmp_node
->next
) != NULL
);
439 /* free the tmp files list */
440 g_list_foreach (files_tmp_list
, (GFunc
)g_object_unref
, NULL
);
441 g_list_free (files_tmp_list
);
443 } while ((node
= node
->next
) != NULL
);
446 static GNUC_INLINE
void
447 sdb_system_do_scan_package_1 (SymbolDBSystem
*sdbs
,
448 SingleScanData
*ss_data
)
450 SymbolDBSystemPriv
*priv
;
454 DEBUG_PRINT ("SCANNING %s",
455 ss_data
->package_name
);
456 exe_string
= g_strdup_printf ("pkg-config --cflags %s",
457 ss_data
->package_name
);
459 g_signal_connect (G_OBJECT (priv
->single_package_scan_launcher
),
460 "child-exited", G_CALLBACK (on_pkg_config_exit
), ss_data
);
462 anjuta_launcher_execute (priv
->single_package_scan_launcher
,
463 exe_string
, on_pkg_config_output
,
469 * Scan the next package in queue, if exists.
472 sdb_system_do_scan_next_package (SymbolDBSystem
*sdbs
)
474 SymbolDBSystemPriv
*priv
;
477 if (g_queue_get_length (priv
->sscan_queue
) > 0)
479 /* get the next one without storing it into queue */
480 SingleScanData
*ss_data
= g_queue_peek_head (priv
->sscan_queue
);
483 sdb_system_do_scan_package_1 (sdbs
, ss_data
);
487 static GNUC_INLINE
void
488 sdb_system_do_engine_scan (SymbolDBSystem
*sdbs
, EngineScanData
*es_data
)
490 SymbolDBSystemPriv
*priv
;
491 GPtrArray
*files_to_scan_array
;
492 GPtrArray
*languages_array
;
494 gboolean special_abort_scan
;
497 special_abort_scan
= es_data
->special_abort_scan
;
499 if (special_abort_scan
== FALSE
)
501 files_to_scan_array
= g_ptr_array_new ();
502 languages_array
= g_ptr_array_new();
504 /* the above arrays will be populated with this function */
505 prepare_files_to_be_scanned (sdbs
, es_data
->cflags
, files_to_scan_array
,
508 symbol_db_engine_add_new_project (priv
->sdbe_globals
, NULL
,
509 es_data
->package_name
, "1.0");
513 files_to_scan_array
= es_data
->files_to_scan_array
;
514 languages_array
= es_data
->languages_array
;
518 /* note the FALSE as last parameter: we don't want
519 * to re-scan an already present file. There's the possibility
520 * infact to have more references of the same files in different
523 proc_id
= symbol_db_engine_add_new_files_full_async (priv
->sdbe_globals
,
524 es_data
->special_abort_scan
== FALSE
?
525 es_data
->package_name
: NULL
,
529 es_data
->special_abort_scan
== FALSE
?
534 /* will be disconnected automatically when callback is called. */
535 g_signal_connect (G_OBJECT (priv
->sdbe_globals
), "scan-end",
536 G_CALLBACK (on_engine_package_scan_end
), es_data
);
538 /* notify the listeners about our intention of adding new files
541 g_signal_emit (sdbs
, signals
[SCAN_PACKAGE_START
], 0,
542 files_to_scan_array
->len
,
543 es_data
->package_name
);
545 /* if no scan has started destroy the engine data here */
548 g_queue_remove (priv
->engine_queue
, es_data
);
549 destroy_engine_scan_data (es_data
);
552 /* having not connected the signal to on_engine_package_scan_end () it's
553 * likely that the queue won't be processed more. So here it is the call
556 /* have we got something left in the queue? */
557 if (g_queue_get_length (priv
->engine_queue
) > 0)
560 es_data
= g_queue_peek_head (priv
->engine_queue
);
562 DEBUG_PRINT ("adding %s", es_data
->package_name
);
563 sdb_system_do_engine_scan (sdbs
, es_data
);
567 if (special_abort_scan
== FALSE
)
569 DEBUG_PRINT ("special_abort_scan");
570 g_ptr_array_foreach (files_to_scan_array
, (GFunc
)g_free
, NULL
);
571 g_ptr_array_free (files_to_scan_array
, TRUE
);
573 g_ptr_array_foreach (languages_array
, (GFunc
)g_free
, NULL
);
574 g_ptr_array_free (languages_array
, TRUE
);
579 on_engine_package_scan_end (SymbolDBEngine
*dbe
, gint process_id
, gpointer user_data
)
581 SymbolDBSystem
*sdbs
;
582 SymbolDBSystemPriv
*priv
;
583 EngineScanData
*es_data
;
585 es_data
= (EngineScanData
*)user_data
;
586 sdbs
= es_data
->sdbs
;
589 /* first of all disconnect the signals */
590 g_signal_handlers_disconnect_by_func (dbe
, on_engine_package_scan_end
,
593 DEBUG_PRINT ("emitting scan_package_end");
594 /* notify listeners that we ended the scan of the package */
595 g_signal_emit (sdbs
, signals
[SCAN_PACKAGE_END
], 0, es_data
->package_name
);
597 /* remove the data from the queue */
598 DEBUG_PRINT ("removing %s", es_data
->package_name
);
599 g_queue_remove (priv
->engine_queue
, es_data
);
600 destroy_engine_scan_data (es_data
);
602 /* have we got something left in the queue? */
603 if (g_queue_get_length (priv
->engine_queue
) > 0)
606 es_data
= g_queue_peek_head (priv
->engine_queue
);
608 DEBUG_PRINT ("adding %s", es_data
->package_name
);
609 sdb_system_do_engine_scan (sdbs
, es_data
);
614 * Scan a new package storing it in queue either for later retrieval or
615 * for signaling the 'busy status'.
618 sdb_system_do_scan_new_package (SymbolDBSystem
*sdbs
,
619 SingleScanData
*ss_data
)
621 SymbolDBSystemPriv
*priv
;
624 if (g_queue_get_length (priv
->sscan_queue
) > 0)
626 /* there's something already working... being this function called in a
627 * single-threaded fashion we can put the the next parameter on the queue
629 DEBUG_PRINT ("%s", "pushed on queue for later scanning");
630 g_queue_push_tail (priv
->sscan_queue
, ss_data
);
634 g_queue_push_tail (priv
->sscan_queue
, ss_data
);
635 sdb_system_do_scan_package_1 (sdbs
, ss_data
);
640 on_pkg_config_exit (AnjutaLauncher
* launcher
, int child_pid
,
641 int exit_status
, gulong time_taken_in_seconds
,
644 SymbolDBSystem
*sdbs
;
645 SymbolDBSystemPriv
*priv
;
646 SingleScanData
*ss_data
;
647 GList
*cflags
= NULL
;
649 ss_data
= (SingleScanData
*)user_data
;
650 sdbs
= ss_data
->sdbs
;
653 /* first of all disconnect the signals */
654 g_signal_handlers_disconnect_by_func (launcher
, on_pkg_config_exit
,
657 if (ss_data
->contents
!= NULL
&& strlen (ss_data
->contents
) > 0)
659 cflags
= sdb_system_get_normalized_cflags (ss_data
->contents
);
662 /* check our ss_data struct. If it has a != null callback then we should
663 * call it right now..
665 if (ss_data
->parseable_cb
!= NULL
)
667 DEBUG_PRINT ("%s", "on_pkg_config_exit parseable activated");
668 ss_data
->parseable_cb (sdbs
, cflags
== NULL
? FALSE
: TRUE
,
669 ss_data
->parseable_data
);
672 /* no callback to call. Just parse the package on */
673 if (ss_data
->engine_scan
== TRUE
&& cflags
!= NULL
)
675 EngineScanData
*es_data
;
677 es_data
= g_new0 (EngineScanData
, 1);
678 es_data
->sdbs
= sdbs
;
679 es_data
->cflags
= cflags
;
680 es_data
->package_name
= g_strdup (ss_data
->package_name
);
681 es_data
->special_abort_scan
= FALSE
;
683 /* is the engine queue already full && working? */
684 if (g_queue_get_length (priv
->engine_queue
) > 0)
686 /* just push the tail waiting for a later processing [i.e. after
687 * a scan-end received
689 DEBUG_PRINT ("pushing on engine queue [length %d] %s",
690 g_queue_get_length (priv
->engine_queue
),
691 es_data
->package_name
);
692 g_queue_push_tail (priv
->engine_queue
, es_data
);
696 /* push the tail to signal a 'working engine' */
697 DEBUG_PRINT ("scanning with engine queue [length %d] %s",
698 g_queue_get_length (priv
->engine_queue
),
699 es_data
->package_name
);
701 g_queue_push_tail (priv
->engine_queue
, es_data
);
703 sdb_system_do_engine_scan (sdbs
, es_data
);
707 /* destroys, after popping, the ss_data from the queue */
708 g_queue_remove (priv
->sscan_queue
, ss_data
);
709 destroy_single_scan_data (ss_data
);
711 /* proceed with another scan */
712 sdb_system_do_scan_next_package (sdbs
);
716 symbol_db_system_scan_package (SymbolDBSystem
*sdbs
,
717 const gchar
* package_name
)
719 SingleScanData
*ss_data
;
721 g_return_val_if_fail (sdbs
!= NULL
, FALSE
);
722 g_return_val_if_fail (package_name
!= NULL
, FALSE
);
724 /* does is already exist on db? */
725 if (symbol_db_system_is_package_parsed (sdbs
, package_name
, "1.0") == TRUE
)
727 DEBUG_PRINT ("symbol_db_system_scan_package (): no need to scan %s",
733 DEBUG_PRINT ("symbol_db_system_scan_package (): NEED to scan %s",
737 /* create the object to store in the queue */
738 ss_data
= (SingleScanData
*)g_new0 (SingleScanData
, 1);
740 /* we don't have chars now. Just fill with the package_name */
741 ss_data
->sdbs
= sdbs
;
742 ss_data
->package_name
= g_strdup (package_name
);
743 ss_data
->contents
= NULL
;
744 ss_data
->parseable_cb
= NULL
;
745 ss_data
->parseable_data
= NULL
;
746 ss_data
->engine_scan
= TRUE
;
748 /* package is a new one. No worries about scan queue */
749 sdb_system_do_scan_new_package (sdbs
, ss_data
);
754 symbol_db_system_is_package_parseable (SymbolDBSystem
*sdbs
,
755 const gchar
* package_name
,
756 PackageParseableCallback parseable_cb
,
759 SingleScanData
*ss_data
;
761 g_return_if_fail (sdbs
!= NULL
);
762 g_return_if_fail (package_name
!= NULL
);
764 /* create the object to store in the queue */
765 ss_data
= (SingleScanData
*)g_new0 (SingleScanData
, 1);
767 /* we don't have chars now. Just fill with the package_name */
768 ss_data
->sdbs
= sdbs
;
769 ss_data
->package_name
= g_strdup (package_name
);
770 ss_data
->contents
= NULL
;
771 ss_data
->parseable_cb
= parseable_cb
;
772 ss_data
->parseable_data
= user_data
;
773 /* this is just an info single_scan_data */
774 ss_data
->engine_scan
= FALSE
;
776 /* package is a new one. No worries about scan queue */
777 sdb_system_do_scan_new_package (sdbs
, ss_data
);
781 symbol_db_system_parse_aborted_package (SymbolDBSystem
*sdbs
,
782 GPtrArray
*files_to_scan_array
,
783 GPtrArray
*languages_array
)
785 SymbolDBSystemPriv
*priv
;
786 EngineScanData
*es_data
;
788 g_return_if_fail (sdbs
!= NULL
);
789 g_return_if_fail (files_to_scan_array
!= NULL
);
790 g_return_if_fail (languages_array
!= NULL
);
794 /* create a special EngineScanData */
795 es_data
= g_new0 (EngineScanData
, 1);
796 es_data
->sdbs
= sdbs
;
797 es_data
->cflags
= NULL
;
798 es_data
->package_name
= g_strdup (_("Resuming glb scan."));
799 es_data
->special_abort_scan
= TRUE
;
800 es_data
->files_to_scan_array
= g_ptr_array_ref (files_to_scan_array
);
801 es_data
->languages_array
= g_ptr_array_ref (languages_array
);
804 DEBUG_PRINT ("SYSTEM ABORT PARSING.....");
806 /* is the engine queue already full && working? */
807 if (g_queue_get_length (priv
->engine_queue
) > 0)
809 /* just push the tail waiting for a later processing [i.e. after
810 * a scan-end received
812 DEBUG_PRINT ("pushing on engine queue %s", es_data
->package_name
);
813 g_queue_push_tail (priv
->engine_queue
, es_data
);
817 DEBUG_PRINT ("aborted package");
818 /* push the tail to signal a 'working engine' */
819 g_queue_push_tail (priv
->engine_queue
, es_data
);
821 sdb_system_do_engine_scan (sdbs
, es_data
);