jwiegley / alert

A Growl-like alerts notifier for Emacs
Other
441 stars 66 forks source link

Race Condition On mode-line Prevents (Meaningful) Restore #71

Open falloutphil opened 6 years ago

falloutphil commented 6 years ago

Hi,

Cool product - I use it extensively to build out alerts for Weechat etc.

I've noticed their is no locking/semaphore on the stored original mode-line face. This means that if alert-mode-line-notify if called twice in quick succession, such that the second call occurs before the corresponding call to alert-mode-line-restore occurs from the first call, a race condition occurs.

Ultimately the value persisted by the first call in alert-saved-mode-line-face is overwritten by the first alert's face. At this point the original face is lost and the alert's face is never restored to its original value.

This happens frequently in reality when using alert with Weechat in a busy discussion!

You can actually avoid this using predicates in the user configuration of alerts as shown below.

But unless I've misunderstood how to define model-line alerts, I don't think they are ever useful without the predicate, and so this should probably be implemented in the Lisp code itself?

To reproduce just execute something like:

(alert "This is an alert" :title "Alert" :severity 'high :category 'chat)  
(alert "This is an alert" :title "Alert" :severity 'high :category 'chat)  

With the alert configuration set to mode-line for any "chat" event.

To fix it using only config you can do the below (this assumes Prelude's mode-line face is default):

 '(alert-user-configuration                                                                                                                                                                                                                             
   (quote                                                                                                                                                                                                                                               
    ((((:category . "chat"))                                                                                                                                                                                                                            
      message                                                                                                                                                                                                                                           
      ((:continue . t)))                                                                                                                                                                                                                                
     (((:category . "chat")                                                                                                                                                                                                                             
       (:predicate lambda                                                                                                                                                                                                                               
                   (name)                                                                                                                                                                                                                               
                   (equal                                                                                                                                                                                                                               
                    (face-attribute                                                                                                                                                                                                                     
                     (quote mode-line)                                                                                                                                                                                                                  
                     :foreground)                                                                                                                                                                                                                       
                    "#8FB28F")))                                                                                                                                                                                                                        
      mode-line                                                                                                                                                                                                                                         
      ((:continue . t))))))