Moin,

On Saturday 27 January 2007 23:32, Christian Stimming wrote:
[...]
> Tatsächlich? Stimmt, jetzt, wo du mich drauf hinweist, sehe ich auch, dass
> GWEN_Gui_free() ein reference-counting macht. Entschuldigung, dass ich das
> übersehen hatte. Allerdings wende ich zu meiner Entlastung ein, dass bisher
> in gwen/aqbanking praktisch alle Funktionen mit dem Namen *_free() nun
> gerade *kein* reference-Counting gemacht hatten und ich deswegen innerhalb
> dieser Funktion auch keines erwartet habe... aber wenn das in GWEN_GUI drin
> ist, wird das in der Tat nicht gelöscht. Das hatte ich also falsch
> verstanden.
[...]
Ich muesste es noch mal nachschauen, aber in Gwen/AqBanking gibt es mehrere 
Beispiele, wo ich Referenz-Counting verwende. Zumindest ueberall dort, wo es 
eine Funktion *_Attach() gibt.

[...]
> Kannst du mir nochmal erklären, was genau du mit "Thread-Variable" meinst?
> Muss die Applikation da was deklarieren oder betrifft das aqbanking/gwen?
[...]

Da gibt es zwei Moeglichkeiten (implementiert ist bisher noch keine davon): 
1.) gwen deklariert das selber (muesste dann also libpthread etc direkt selber 
verwenden, ohne es eigentlich selber zu benoetigen)
2.) man aendert die bisherige Funktion GWEN_Gui_GetGui() in eine Funktion um, 
die von der Anwendung ausgefuehrt wird und lediglich die Aufgabe hat, die 
GUI-Implementierung herauszuruecken (das aktive GUI-Objekt). Die Entscheidung 
naemlich, ob Mutlithreading ueberhaupt zum Einsatz kommt, trifft ja die 
Anwendung. Diese koennte dann halt statt einen statischen Pointer zu 
verwenden einen Pointer als Thread-Variable halten (also den Pointer fuer 
jeden Thread).

[...]
> > Letztlich kann das ziemliche Ausmasse annehmen. In Libchipcard habe ich
> > aufgehoert, als absehbar war, dass jede diesbezuegliche Funktion der
> > Libchipcard-API einen solchen Pointer haben muesste.
>
> Ok. Wenn du nun gerade in libchipcard definitiv sagst, dass das (wegen
> sockets etc) praktisch unmöglich ist, das GUI-callback-Objekt
> nicht-statisch einzubauen, dann seh ich das für diesen Bereich ein.
[...]

Es ist lediglich so, dass es mir in Libchipcard aufgefallen ist, das Problem 
betrifft aber AqBanking selbst wahrscheinlich noch viel mehr.

Mein Vorgehen war 
1.) Gwen anzupassen, so dass die besprochenen Objekte einen GUI-Pointer 
mitbekommen. 
2.) als naechstes habe ich dann den ganzen Code angepasst, der die geaenderten 
Konstruktoren aufgerufen hat (nochmal eine ganze Menge Arbeit). 
3.) als naechstes habe ich - der Dependency-Liste folgend - Libchipcard3 
angepasst. Und schon hier kam es zu massiven Schwierigkeiten (abgesehen 
davon, dass ich damit auch eine neue Major-Release von Libchipcard machen 
muesste).

Das Problem ist halt, dass manchen Objekten nicht schon zum Zeitpunkt ihrer 
Erzeugung - also beim Aufruf des Konstruktors - ein GUI-Pointer zugeordnet 
werden kann. Das einfachste Beispiel war halt der Socket, aber es geht schon 
beim Initialisieren von Libchipcard los. Zu dem Zeitpunkt findet noch gar 
keine Interaktion statt, also kann ich keinen aktiven GUI-Pointer uebergeben.

Schlimmer noch, spaeter - wenn tatsaechlich Aktionen abgearbeitet werden - 
muesste der GUI-Pointer im Socket etc ja eigentlich geaendert werden auf die 
GUI, fuer die der aktuelle Aufruf einer Socket-Funktion gerade gemacht wird. 
Was passiert aber, wenn dieser Aufruf beendet ist? Dann muesste man den 
vorher aktiven Pointer wieder zuruecksetzen, also muesste man sich den vor 
dem Aufruf merken. Das kann man nur umgehen, wenn man nun stattdessen in 
jedem Aufruf einer Socket-Funktion den Pointer direkt mitgibt.
Das wiederum zieht einen ganzen Rattenschwanz nach sich, weil ja schliesslich 
die Aufrufer in der gleichen Manier an den GUI-Pointer kommen muessen.

An dieser Stelle habe ich bei Libchipcard abgebrochen, und ich kann mir nur 
vorstellen, wie das in AqBanking aussehen wuerde.

Deshalb halte ich den Weg, einen GUI-Pointer fuer jede Aktion zu halten, fuer 
nicht gangbar. Bei Funktionen, die direkt Interaktion veranlassen koennen - 
wie bei den Socket-Funktionen - waere es dem Aufruder noch zu vermitteln, 
warum er hier einen GUI-Pointer mitgeben muss. Bei indirekten Funktionen, die 
eventuell ueber mehrere Ecken Interaktion in einer tieferen Ebene ausloesen 
koennten, wird es schon schwieriger, das zu vermitteln.

Man moege aber festhalten, dass die GUI-Geschichte ein paralleles Abarbeiten 
mehrere Aktionen nicht verhindert. Die Anwendung muesste nur intelligent mit 
der GUI-Implementierung reagieren.

Das einzige Problem stellen nach meiner Ansicht die Progress-Funktionen dar. 
Hier koennte aber eine Anwendung das ganze auch so loesen, wie ich in einem 
Screenshot von KDE4 gesehen habe: Einfach alle Fortschritte in einem Fenster 
sammeln und dieses Fenster erst schliessen (lassen), wenn alle enthaltenen 
Progresse abgeschlossen sind. Absolut alle Progress-Funktionen koennen 
anschliessend gesichert einem bestimmten Progress zugeordnet werden, weil ja 
ProgressStart() eine ID zurueckliefert und wir diese in unseren Aufrufen 
verwenden (wo das nicht getan wird, sollte das geaendert werden, das betrifft 
zumeist GWEN_Gui_ProgressLog()).

[...]
> Trotzdem würd ich vorschlagen, ob das nicht für andere Teilbereiche
> nicht-statisch realisiert werden könnte. Prominentes Beispiel wäre eben das
> "MT940-Datei-Import" in aqbanking, welches ja ein vollwertiges
> AB_BANKING-Objekt benötigt, aber vom tatsächlichen Ablauf her IIRC wirklich
[...]
Rein theoretisch ist es uebrigend erstmals im derzeitigen AqBanking3 
ueberhaupt moeglich, parallel zu anderen Aktionen auch Importe und Exporte zu 
machen (weil die vom Online-Banking getrennt sind).

[...]
> eigentlich als Ziel anstreben würde, in GUI-Hinsicht thread-safe zu werden
> (und static GUI-Objekte zu vermeiden), aber dann eben als *Ausnahme* dieses
> an mehreren Stellen nicht bieten kann, weil's zu schwierig wird in der
> Implementierung (libchipcard). Bei libchipcard seh ich die Situation von
> der Natur der Sache her schon näher an einer static-Variable: Du hast da
> nur *einen* chipcard-Daemon, was also schon mal eine ganz andere Situation
> als bei Datei-Import oder RDH-keyfile-Aktionen ist. Aber deshalb fände ich
[...]
Das stimmt so nicht: Es gibt nicht immer nur einen Daemon, aber selbst wenn, 
es kann immer auch mehrere Clients geben, und zwar auch innerhalb eines 
Prozesses. Daher ist es hier genauso wichtig, das das mit der GUI einheitlich 
zum Verhalten in AqBanking ist.

Eine statische Variable ist uebrigends ueberhaupt kein Hindernis fuer 
Thread-Sicherheit: Sogar im Gegenteil, wenn mehrere Aktionen parallel 
ausgefuehrt werden, und der GUI-Pointer in der Thread-Variable gehalten wird, 
hat man derzeit die absolut beste Trennung. Darum denke ich auch, dass 
zunaechst einmal in diese Richtung vorgearbeitet werden sollte.

[...]
> Re parallele AB_BANKING-Objekte und Konfiguration: Wie gesagt: Mein
> Beispiel ist einerseits MT940-Import und andererseits HBCI-Download
> parallel. Der Import ändert IIRC an der Konfiguration nichts. Von daher
[...]

Richtig, deshalb duerfte das auch jetzt schon im aktuellen AqBanking moeglich 
sein - bzw - fast. Mir faellt gerade ein, dass ich ja die Initialisierung der 
Pfade noch in AB_Banking_Init() drin habe, Ich denke, ich weiss, wie ich das 
umgehen kann...

Wie gesagt, das Problem mit der GUI ist kein Hindernisgrund fuer parallele 
Abarbeitung von Aufgaben.


Gruss
Martin

-- 
"Things are only impossible until they're not"

AqBanking - http://www.aqbanking.de/
LibChipcard - http://www.libchipcard.de/

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Aqbanking-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/aqbanking-devel

Reply via email to