aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-03-13 11:29:03 +0100
committerAlex Auvolat <alex@adnab.me>2020-03-13 11:29:03 +0100
commitad8461491b35c739683971deff32a3203d0d7e5d (patch)
treeb84f4e59b3a4771b0449714bce22ca78f1074fb3
parent6292303a31e9098e8803c9544fc0785023d526fd (diff)
downloadeasybridge-ad8461491b35c739683971deff32a3203d0d7e5d.tar.gz
easybridge-ad8461491b35c739683971deff32a3203d0d7e5d.zip
Avoid occasionnal deadlocks (1 in 256)
-rw-r--r--account.go9
-rw-r--r--server.go3
-rw-r--r--util.go6
3 files changed, 9 insertions, 9 deletions
diff --git a/account.go b/account.go
index b0313a4..0b480d6 100644
--- a/account.go
+++ b/account.go
@@ -453,17 +453,16 @@ func (a *Account) eventInternal(event *Event) error {
var cache_key string
if event.Id != "" {
+ // Use mx_room_id as a lock slot key, because this section is
+ // concurrent with the part that sends events out in server.go,
+ // and at that point we don't know the event's ID yet
+ // since it will be attributed by the backend during the call to send
dbLockSlot(mx_room_id)
defer dbUnlockSlot(mx_room_id)
// If the event has an ID, make sure it is processed only once
cache_key = fmt.Sprintf("%s/event_seen/%s/%s",
a.Protocol, mx_room_id, event.Id)
- slot_key := dbKvSlotKey(cache_key)
-
- dbLockSlot(slot_key)
- defer dbUnlockSlot(slot_key)
-
if dbKvGet(cache_key) == "yes" {
// false: cache key was not modified, meaning we
// already saw the event
diff --git a/server.go b/server.go
index 1654971..1868078 100644
--- a/server.go
+++ b/server.go
@@ -166,6 +166,7 @@ func handleTxnEvent(e *mxlib.Event) error {
ev.Author = acct.Conn.User()
ev.Room = room.RoomID
+ // use room id as lock slot key, see account.go in eventInternal
dbLockSlot(e.RoomId)
defer dbUnlockSlot(e.RoomId)
@@ -173,7 +174,7 @@ func handleTxnEvent(e *mxlib.Event) error {
if err == nil && created_ev_id != "" {
cache_key := fmt.Sprintf("%s/event_seen/%s/%s",
room.Protocol, e.RoomId, created_ev_id)
- dbKvPut(cache_key, "yes")
+ dbKvPutLocked(cache_key, "yes")
}
return err
} else {
diff --git a/util.go b/util.go
index 4e23bb1..cd16a59 100644
--- a/util.go
+++ b/util.go
@@ -27,15 +27,15 @@ func ezbrSystemRoom(user_mx_id string) (string, error) {
}
widget_kv_key := "ezbr_widget_on:" + mx_room_id
- if config.WebURL != "" && dbKvTestAndSet(widget_kv_key, "yes") {
+ if config.WebURL != "" && dbKvGet(widget_kv_key) != "yes" {
widget := map[string]interface{}{
"type": "m.easybridge",
"url": config.WebURL,
"name": "Easybridge account configuration dashboard",
}
err = mx.PutStateAs(mx_room_id, "im.vector.modular.widgets", "ezbr_widget", widget, ezbrMxId())
- if err != nil {
- dbKvPut(widget_kv_key, "")
+ if err == nil {
+ dbKvPut(widget_kv_key, "yes")
}
}