XBMC unter 12.04

Im Rahmen meines Wechsels von Ubuntu 10.04 bis 12.04 musste als erstes mein HTPC dran glauben. Das ganze ging recht Problemlos von statten. Einzig der NoDM hatte Probleme bereitet. NoDM erwartet den XServer unter /usr/bin/X. Ubuntu 12.04 stellt selbigen aber (ohne Link) unter /usr/bin/Xorg zur Verfügung. Da musste mit einem Link nachgeholfen werden.

Danach lief sofort XBMC hoch, ohne weitere Probleme. Danach begann jedoch die Detailarbeit.

Wie gehabt muss nachgeholfen werden, wenn man vie XBMC den Rechner runter fahren möchte. Dazu bedarf es der Packete policykit-1, upower und acpi-support.

sudo aptitude install policykit-1 upower acpi-support

anschließend müssen dem XBMC-User die entsprechenden Rechte eingeräumt werden:
File /var/lib/polkit-1/localauthority/50-local.d/xbmc-actions.pkla

[Actions for xbmc user]
Identity=unix-user:xbmc-user
Action=org.freedesktop.upower.*;org.freedesktop.consolekit.system.*;org.freedesktop.udisks.*
ResultAny=yes
ResultInactive=yes
ResultActive=yes

Danach kann man über die entsprechenden Menüs/Kommandos aus XBMC heraus den Rechner Ausschalten, Schlafen legen oder in den Hibernate schicken.

Um den Rechner wieder aufzuwecken bedurfte es eines weiteren Kniffs. Die Schnittstelle, wie man ein USB Device für das Aufwecken markiert hat sich verändert. Ich musste es wie folgt erweitern:

#!/bin/sh
echo "USB0" > /proc/acpi/wakeup
echo "USB2" > /proc/acpi/wakeup
echo enabled > /sys/bus/usb/devices/3-1/power/wakeup
echo enabled > /sys/bus/usb/devices/usb1/power/wakeup
echo enabled > /sys/bus/usb/devices/usb2/power/wakeup
echo enabled > /sys/bus/usb/devices/usb3/power/wakeup
echo enabled > /sys/bus/usb/devices/usb4/power/wakeup

Interessanterweise war die „Breitbandfreigabe“ nur für den Suspend nötig. Um aus den Hibernate aufzuwachen reichte es das 3-1 Device zu „enablen“. Ich hab das Script auch nicht mehr in der rc.local verlink sondern lasse es vor und nach jeden Suspend/Hibernate ausführen, indem es unter /etc/pm/sleep.d abgelegt wurde.

Ein letzer Kniff war nötig damit sich das DVD-Laufwerk nach dem mounten auswerfen lies. Dazu musste ich in der /lib/udev/ruled.d/60-cdrom_id.rules die folgende Zeile ändern.

IMPORT{program}="cdrom_id --lock-media $tempnode"

So sollte es aussehen, dann lässt sich das Laufwerk jederzeit öffnen.

IMPORT{program}="cdrom_id $tempnode"

Quellen:

Zwei Jahre Ubuntu 10.04 – Zeit für einen Wechsel

Seit dem 29 April 2010 betreibe ich meinen HomeServer mit Ubuntu LucidLynx. Danach hab ich suxesive meine ganze Rechner auf den Langläufer umgestellt. Die folgenden zwei Jahren waren die ruhigsten in meiner ganzen Zeit, die ich mit Computern zu tun hab.

In der ganzen Zeit ereilten mich nur zwei „schwere Fehler“ (GAUs) die ich nicht auf meine eigene Dummheit zurückführen konnte. Gleich zu beginn Zerschoss mir der GRUB-Installer mein verschlüsseltes Storage indem der Bootsektor den Kryptoheader überschrieben hat obwohl ich eine andere Platte als Bootloader-Ziel angegeben habe. Der zweite GAU ereignete sich durch ein defektes Update, der die Netbook-Version unbenutzbar machte.

Beide Fehler liesen jedoch mit überschaubarem Aufwand beheben. Alle weiteren Fehler waren auf die eigene Dummheit zurückzuführen. Alles in allem hat sich der LTS-Release als sehr robust erwiesen. Jetzt wird es Zeit Abschied zu nehmen und auf die neue Version umzusteigen, hoffentlich werden die folgenden 2 Jahre genauso entspannt wie die bisherigen.

Android: Multithreading mit AsyncTask und Deadlocks

Wenn man für Android Anwendungen entwickelt kommt man sehr schnell mit dem AsyncTask in Kontakt. Immer dann, wenn etwas länger dauern kann, soll man diese Klasse benutzten, so der Tenor in fast allen Tutorials, Blog-Einträgen und Offiziellen Developer-Guides. Was seltener zur Sprache kommt ist folgender Umstand: unterschiedliche AsyncTask-Instanzen sind nicht unabhängig voneinander.  Standardmäßig laufen alle AsnycTask auf einem „Executor“, einem ThreadPool. Jeh nach AndroidVersion ist dieser auf Serielle Verarbeitung eingestellt (ein WorkerThread) oder stellt fünf WorkerThreads bereit.

Als Entwickler kann man dies aber auch vorgeben oder gleich einen eigenen ThreadPool mitgeben. Das Problem bleibt aber das gleiche: man kommt wahnsinnig schnell in die Versuchung zwei AsyncTask logisch zu verschalten oder aus einem Task einen mehrere Task zu erzeugen und auf deren Ergebnisse zu werten (scatter – gather). Die Anzahl der WorkerThreads legt nun fest wie schnell das ganze in die Hose geht. Bei einem WorkerThread braucht es solange bis der erste „wartende“ AsyncTask anfängt zu warten, danach kommt kein andere AsyncTask mehr zum Zug. Bei zwei oder mehr WorkerThreads kann es immer gut gehen oder zu der Situation kommen, dass alle Threads auf Tasks warten die noch gar nicht ausgeführt werden. Ein klassisches logisches DeadLock. Die Anwendung „hängt“, Android bekommt es nicht mit, weil der UI Thread nicht blockiert ist und der User schimpft.

Das ganze kann man umgehen indem man nicht „unbegrenzt“ auf ein Ergebnis wartet (AsyncTask.get mit Zeitspanne aufrufen), die Abhängigkeiten anderes gestaltet oder mehrere unterschiedliche ThreadPools verwendet. Das Grundproblem ist aber, ein einmal erzeugter AsyncTask(.execute) wird genau einmal ausgeführt. Man kann ihn nicht vom Stack nehmen, nicht wieder einqueuen oder sonst wie an der Ausführungsreihenfolge drehen.

Glücklicherweise stellt Google die Klasse im Rahmen seiner OpenSource-Strategie die AsyncTask-Quelldatei zur Verfügung, so dass man sich relativ einfach seine eigene AsyncTask-Variante nach eigenem Bedarf zusammenbauen kann.

Ich hab das z.B gemacht um einen dedizierten Thread zu haben, bei dem immer wieder Task eingequeued werden können und sequenziell in einer definierten Reihenfolge (FIFO) abgearbeitet werden.

Sources: RepeatingTask

Grundsätzlich bleibt aber gültig: wer Multithreading betreibt, weiß was er da tut oder kommt in die Hölle.