summary refs log tree commit diff stats
Commit message (Collapse)AuthorAgeFilesLines
* lib/ui: fix Grid race conditionSimon Ser2019-05-051-1/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This was is more complicated than others. The cells list is accessed by multiple goroutines: - Some change the Grid's contents via AddChild/RemoveChild - Some call Draw - Some invalidate the grid via Invalidate Invalidate calls are tricky to handle because they will also invalidate all child cells. This will inturn trigger the cellInvalidated callback, which needs to read the list of cells. For this reason, we use a sync.RWLock which allows multiple concurrent reads. Below is the race fixed by this commit. Read at 0x00c0000bc3d0 by goroutine 7: git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Grid).cellInvalidated() /home/simon/src/aerc2/lib/ui/grid.go:181 +0x45 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Grid).cellInvalidated-fm() /home/simon/src/aerc2/lib/ui/grid.go:179 +0x55 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Invalidatable).DoInvalidate() /home/simon/src/aerc2/lib/ui/invalidatable.go:22 +0x85 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Bordered).contentInvalidated-fm() /home/simon/src/aerc2/lib/ui/borders.go:39 +0x56 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Invalidatable).DoInvalidate() /home/simon/src/aerc2/lib/ui/invalidatable.go:22 +0x85 git.sr.ht/~sircmpwn/aerc2/widgets.NewDirectoryList.func1() /home/simon/src/aerc2/widgets/dirlist.go:81 +0x55 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Invalidatable).DoInvalidate() /home/simon/src/aerc2/lib/ui/invalidatable.go:22 +0x85 git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start.func1() /home/simon/src/aerc2/widgets/spinner.go:88 +0x82 Previous write at 0x00c0000bc3d0 by main goroutine: [failed to restore the stack] Goroutine 7 (running) created at: git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start() /home/simon/src/aerc2/widgets/spinner.go:46 +0x98 git.sr.ht/~sircmpwn/aerc2/widgets.NewDirectoryList() /home/simon/src/aerc2/widgets/dirlist.go:37 +0x28b git.sr.ht/~sircmpwn/aerc2/widgets.NewAccountView() /home/simon/src/aerc2/widgets/account.go:49 +0x5ca git.sr.ht/~sircmpwn/aerc2/widgets.NewAerc() /home/simon/src/aerc2/widgets/aerc.go:60 +0x807 main.main() /home/simon/src/aerc2/aerc.go:65 +0x33e
* lib/msgstore: protect with a mutexSimon Ser2019-04-292-3/+40
| | | | | | MessageStore has a lot of exported fields that can be read from the outside. Each read must be protected, because a call from Update could happen at any time.
* widgets/msglist: fix MessageList.store raceSimon Ser2019-04-291-23/+32
| | | | | This field could be written to in the middle of a Draw call, which reads it multiple times. Use an atomic variable instead.
* worker/imap: use the IMAP connection from a single goroutineSimon Ser2019-04-293-86/+77
| | | | | | | | | | | | | Unfortunately, the IMAP protocol hasn't been designed to be used from multiple goroutines at the same time. For instance, if you fetch twice the same message from two different goroutines, it's not possible to tell whether the response is for one receiver or the other. For this reason, go-imap clients aren't safe to use from multiple goroutines. This commit changes the IMAP workers to be synchronous again (a command is executed only after the previous one has completed). To use IMAP from different threads, popular clients (e.g. Thunderbird) typically open multiple connections.
* Update go-imap to 1.0.0-beta.4Simon Ser2019-04-292-47/+29
| | | | This release contains race conditions fixes.
* lib/ui: fix GridCell.invalid raceSimon Ser2019-04-291-5/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is read/written from different goroutines. Write at 0x00c00009c6f0 by goroutine 7: git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Grid).cellInvalidated() /home/simon/src/aerc2/lib/ui/grid.go:189 +0x122 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Grid).cellInvalidated-fm() /home/simon/src/aerc2/lib/ui/grid.go:178 +0x55 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Invalidatable).DoInvalidate() /home/simon/src/aerc2/lib/ui/invalidatable.go:22 +0x85 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Bordered).contentInvalidated-fm() /home/simon/src/aerc2/lib/ui/borders.go:39 +0x56 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Invalidatable).DoInvalidate() /home/simon/src/aerc2/lib/ui/invalidatable.go:22 +0x85 git.sr.ht/~sircmpwn/aerc2/widgets.NewDirectoryList.func1() /home/simon/src/aerc2/widgets/dirlist.go:81 +0x55 git.sr.ht/~sircmpwn/aerc2/lib/ui.(*Invalidatable).DoInvalidate() /home/simon/src/aerc2/lib/ui/invalidatable.go:22 +0x85 git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start.func1() /home/simon/src/aerc2/widgets/spinner.go:88 +0x82 Previous write at 0x00c00009c6f0 by main goroutine: [failed to restore the stack] Goroutine 7 (running) created at: git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start() /home/simon/src/aerc2/widgets/spinner.go:46 +0x98 git.sr.ht/~sircmpwn/aerc2/widgets.NewDirectoryList() /home/simon/src/aerc2/widgets/dirlist.go:37 +0x28b git.sr.ht/~sircmpwn/aerc2/widgets.NewAccountView() /home/simon/src/aerc2/widgets/account.go:49 +0x5ca git.sr.ht/~sircmpwn/aerc2/widgets.NewAerc() /home/simon/src/aerc2/widgets/aerc.go:60 +0x807 main.main() /home/simon/src/aerc2/aerc.go:65 +0x33e
* lib/ui: introduce InvalidatableSimon Ser2019-04-2712-127/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Many Drawable implementations have their own Invalidate and OnInvalidate functions, with an unexported onInvalidate field. However OnInvalidate and Invalidate are usually not called in the same goroutine. This results in a race on this field, e.g.: Read at 0x00c000094748 by goroutine 7: git.sr.ht/~sircmpwn/aerc2/widgets.NewDirectoryList.func1() /home/simon/src/aerc2/widgets/dirlist.go:85 +0x56 git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start.func1() /home/simon/src/aerc2/widgets/spinner.go:93 +0x1bb Previous write at 0x00c000094748 by main goroutine: [failed to restore the stack] Goroutine 7 (running) created at: git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start() /home/simon/src/aerc2/widgets/spinner.go:46 +0x8f git.sr.ht/~sircmpwn/aerc2/widgets.NewDirectoryList() /home/simon/src/aerc2/widgets/dirlist.go:37 +0x286 git.sr.ht/~sircmpwn/aerc2/widgets.NewAccountView() /home/simon/src/aerc2/widgets/account.go:50 +0x5ca git.sr.ht/~sircmpwn/aerc2/widgets.NewAerc() /home/simon/src/aerc2/widgets/aerc.go:60 +0x800 main.main() /home/simon/src/aerc2/aerc.go:65 +0x33e To fix this, introduce a new type, Invalidatable, which protects the field. Unfortunately the Drawable must be passed to the callback function in Invalidate, so we still need to re-implement this in each Invalidatable user.
* worker/types: fix Worker.Callbacks race conditionSimon Ser2019-04-272-21/+42
| | | | | | | | | | | | | Worker.Process* functions were called in different goroutines than Worker.Post*. Protect the map with a mutex. Also make the map unexported to prevent external unprotected accesses. Worker.Process* functions used to delete items from the map. However they didn't delete the element they retrieved: callbacks[msg.InResponseTo()] was read while callbacks[msg] was deleted. I'm not sure I understand why. I tried to delete the element that was accessed - but this broke everything (UI froze at "Connecting..."). I don't believe any elements were actually removed from the map, so the new code just doesn't remove anything.
* widgets/spinner: fix Spinner.frame raceSimon Ser2019-04-271-12/+15
| | | | | | | | | | | | | | | | | | | | | | | | It's accessed by the goroutine which increments it and the goroutine that draws the widget at the same time. Use atomic instead. Write at 0x00c00000ebc0 by goroutine 7: git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start.func1() /home/simon/src/aerc2/widgets/spinner.go:50 +0x169 Previous read at 0x00c00000ebc0 by main goroutine: [failed to restore the stack] Goroutine 7 (running) created at: git.sr.ht/~sircmpwn/aerc2/widgets.(*Spinner).Start() /home/simon/src/aerc2/widgets/spinner.go:44 +0x8b git.sr.ht/~sircmpwn/aerc2/widgets.NewDirectoryList() /home/simon/src/aerc2/widgets/dirlist.go:37 +0x286 git.sr.ht/~sircmpwn/aerc2/widgets.NewAccountView() /home/simon/src/aerc2/widgets/account.go:50 +0x5ca git.sr.ht/~sircmpwn/aerc2/widgets.NewAerc() /home/simon/src/aerc2/widgets/aerc.go:60 +0x800 main.main() /home/simon/src/aerc2/aerc.go:65 +0x33e
* go get git.sr.ht/~sircmpwn/go-libvtermElias Naur2019-04-212-1/+5
| | | | Signed-off-by: Elias Naur <mail@eliasnaur.com>
* Fix segfault on :select-message for unloaded messagesTom Lebreux2019-04-171-0/+3
| | | | Signed-off-by: Tom Lebreux <tomlebreux@cock.li>
* Re-render terminal on invalidateDrew DeVault2019-04-151-4/+13
|
* Fix segfault on :view-message for unloaded messageTom Lebreux2019-04-102-0/+10
| | | | | | This also fixes segfault on :view-message on empty directory Signed-off-by: Tom Lebreux <tomlebreux@cock.li>
* Lowercase MIME types while matching filtersGokberk Yaltirakli2019-04-071-1/+2
|
* Clear damage on each terminal.Draw callDrew DeVault2019-04-051-0/+2
|
* Fix wrong row due to typoTom Lebreux2019-04-051-1/+1
| | | | Signed-off-by: Tom Lebreux <tomlebreux@cock.li>
* Fix infinite loop on empty DirectoryContentsTom Lebreux2019-04-051-2/+4
| | | | | | | | | When changing to an empty directory, ml.selected is 0, and the length of ml.store.Uids is 0. The loop condition is always true so we have an infinite loop causing 100% CPU usage and prevents us to change to other directories. Signed-off-by: Tom Lebreux <tomlebreux@cock.li>
* Show (no messages) for empty foldersDrew DeVault2019-04-041-0/+6
|
* Use better regex for identifying patchesDrew DeVault2019-03-311-1/+1
|
* Remove show-headers config optionDrew DeVault2019-03-311-6/+0
| | | | This'll probably look different when we implement it
* Remove unused config optionsDrew DeVault2019-03-311-6/+0
| | | | Which are not planned for eventual implementation
* Remove key bindings from aerc.confDrew DeVault2019-03-311-46/+0
| | | | These were moved to binds.conf
* Add script for sandboxing w3mDrew DeVault2019-03-312-1/+11
|
* Remove extra debug statementDrew DeVault2019-03-311-1/+0
|
* Use shell to execute filters, fix non-determinismDrew DeVault2019-03-312-7/+5
|
* Make tab width of :pipe consistentDrew DeVault2019-03-311-5/+3
|
* Improve plaintext.pyDrew DeVault2019-03-312-3/+2
|
* Implement header-regex-match filtersDrew DeVault2019-03-313-8/+39
|
* Improve error handling in message viewerDrew DeVault2019-03-311-10/+36
| | | | Still not great but at least it tells you when something went wrong
* Add basic filter implementationDrew DeVault2019-03-316-42/+142
|
* Decode messages before rendering themDrew DeVault2019-03-311-2/+22
|
* Add plaintext highlighter, escape ANSI in sourceDrew DeVault2019-03-312-1/+25
|
* Make message viewer real, part twoDrew DeVault2019-03-314-23/+38
|
* Rename FetchMessageBodies to FetchFullMessagesDrew DeVault2019-03-315-17/+17
|
* Make the message viewer real, part oneDrew DeVault2019-03-317-130/+124
|
* Don't parse mail in worker; send a reader insteadDrew DeVault2019-03-316-57/+13
|
* Pull BodyStructure up from IMAP workerDrew DeVault2019-03-313-10/+40
|
* Add message view commands, :closeDrew DeVault2019-03-306-5/+47
|
* Update default config/binds.confDrew DeVault2019-03-301-2/+17
|
* Minor refactoring to header viewDrew DeVault2019-03-301-7/+12
|
* Fix crash on command not foundDrew DeVault2019-03-301-37/+42
|
* Handle no configured accounts gracefullyJulian P Samaroo2019-03-301-0/+4
| | | | | Instead of throwing a runtime error, when no accounts are configured in accounts.conf, we provide an informative error message.
* Use bold instead of inverted for header namesDrew DeVault2019-03-301-2/+3
|
* Add multipart selector mockup to msgviewerDrew DeVault2019-03-301-7/+50
|
* Actually, git uses cyan for line markersDrew DeVault2019-03-301-1/+1
|
* Update hldiff.py to match git more closelyDrew DeVault2019-03-301-2/+10
|
* Add basic message viewer mockupDrew DeVault2019-03-309-73/+257
|
* Correct color of error messagesDrew DeVault2019-03-304-7/+7
|
* Use tcell.Style.Reverse instead of black on whiteDrew DeVault2019-03-307-22/+25
|
* Implement :pipeDrew DeVault2019-03-305-7/+91
|