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
