1
0

After a research on how mutexes work, a mutex bcame embedded. And locks should be invoke from outside.

This commit is contained in:
Alexander Andreev 2024-05-22 04:05:15 +04:00
parent 2facf9662a
commit baad7da10d
Signed by: Arav
GPG Key ID: 25969B23DCB5CA34
3 changed files with 13 additions and 17 deletions

View File

@ -62,6 +62,8 @@ func main() {
log.Printf("Failed to fetch last N songs: %s\n", err) log.Printf("Failed to fetch last N songs: %s\n", err)
} }
lstnrs.RLock()
defer lstnrs.Unlock()
web.Index(&currentSong, lst, *songListLen, lstnrs, r).Render(context.Background(), w) web.Index(&currentSong, lst, *songListLen, lstnrs, r).Render(context.Background(), w)
}) })
@ -112,6 +114,8 @@ func main() {
switch <-sysSignal { switch <-sysSignal {
case os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT, syscall.SIGSEGV: case os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGABRT, syscall.SIGSEGV:
if currentSong.Artist != "" { if currentSong.Artist != "" {
lstnrs.Lock()
defer lstnrs.Unlock()
currentSong.Listeners, currentSong.PeakListeners = lstnrs.Reset() currentSong.Listeners, currentSong.PeakListeners = lstnrs.Reset()
if err := stats.Add(&currentSong); err != nil { if err := stats.Add(&currentSong); err != nil {
log.Println("failed to save a current song during a shutdown:", err) log.Println("failed to save a current song during a shutdown:", err)

View File

@ -42,8 +42,12 @@ func (dj *DJHandlers) ListenersUpdateIcecast(w http.ResponseWriter, r *http.Requ
switch r.FormValue("action") { switch r.FormValue("action") {
case "listener_add": case "listener_add":
dj.listeners.Lock()
_ = dj.listeners.Inc() _ = dj.listeners.Inc()
dj.listeners.Unlock()
case "listener_remove": case "listener_remove":
dj.listeners.Lock()
defer dj.listeners.Unlock()
if _, err := dj.listeners.Dec(); err != nil { if _, err := dj.listeners.Dec(); err != nil {
log.Println("DJHandlers.ListenersUpdateIcecast:", err) log.Println("DJHandlers.ListenersUpdateIcecast:", err)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
@ -107,7 +111,9 @@ func (dj *DJHandlers) PlaylistNext(w http.ResponseWriter, _ *http.Request) {
newSong.Artist = "Nothing to play. Playing a fallback: " + newSong.Artist newSong.Artist = "Nothing to play. Playing a fallback: " + newSong.Artist
} }
dj.listeners.Lock()
dj.curSong.Listeners, dj.curSong.PeakListeners = dj.listeners.Reset() dj.curSong.Listeners, dj.curSong.PeakListeners = dj.listeners.Reset()
dj.listeners.Unlock()
if dj.curSong.Artist != "" && !strings.Contains(dj.curSong.Artist, "no artist tag") && if dj.curSong.Artist != "" && !strings.Contains(dj.curSong.Artist, "no artist tag") &&
!strings.Contains(dj.curSong.Artist, "No title tag") { !strings.Contains(dj.curSong.Artist, "No title tag") {
@ -131,6 +137,8 @@ func (dj *DJHandlers) Status(w http.ResponseWriter, r *http.Request) {
log.Println("failed to fetch last n songs:", err) log.Println("failed to fetch last n songs:", err)
} }
dj.listeners.RLock()
defer dj.listeners.Unlock()
err = json.NewEncoder(w).Encode(&struct { err = json.NewEncoder(w).Encode(&struct {
Current *radio.Song `json:"current_song,omitempty"` Current *radio.Song `json:"current_song,omitempty"`
Listeners int64 `json:"listeners"` Listeners int64 `json:"listeners"`

View File

@ -9,7 +9,7 @@ import (
// ListenerCounter stores the current, overall and peak numbers of listeners. // ListenerCounter stores the current, overall and peak numbers of listeners.
type ListenerCounter struct { type ListenerCounter struct {
mutex sync.RWMutex sync.RWMutex
current, peak int64 current, peak int64
overall, cur_peak int64 overall, cur_peak int64
} }
@ -21,36 +21,26 @@ func NewListenerCounter() *ListenerCounter {
// Current returns a number of current listeners. // Current returns a number of current listeners.
func (l *ListenerCounter) Current() int64 { func (l *ListenerCounter) Current() int64 {
l.mutex.RLock()
defer l.mutex.RUnlock()
return l.current return l.current
} }
// Peak returns a peak number of listeners. // Peak returns a peak number of listeners.
func (l *ListenerCounter) Peak() int64 { func (l *ListenerCounter) Peak() int64 {
l.mutex.RLock()
defer l.mutex.RUnlock()
return l.peak return l.peak
} }
// CurrentPeak returns a peak number of listeners for a currently playing song. // CurrentPeak returns a peak number of listeners for a currently playing song.
func (l *ListenerCounter) CurrentPeak() int64 { func (l *ListenerCounter) CurrentPeak() int64 {
l.mutex.RLock()
defer l.mutex.RUnlock()
return l.cur_peak return l.cur_peak
} }
// Overall returns an overall number of listeners for a currently playing song. // Overall returns an overall number of listeners for a currently playing song.
func (l *ListenerCounter) Overall() int64 { func (l *ListenerCounter) Overall() int64 {
l.mutex.RLock()
defer l.mutex.RUnlock()
return l.overall return l.overall
} }
// Inc increments by 1 a current number of listeners and updates a peak number. // Inc increments by 1 a current number of listeners and updates a peak number.
func (l *ListenerCounter) Inc() int64 { func (l *ListenerCounter) Inc() int64 {
l.mutex.Lock()
defer l.mutex.Unlock()
if l.current == math.MaxInt64 { if l.current == math.MaxInt64 {
// We panic here because if this will ever happen, then something's going certainly wrong. // We panic here because if this will ever happen, then something's going certainly wrong.
panic("a current number of listeners exceeded MaxInt64") panic("a current number of listeners exceeded MaxInt64")
@ -72,8 +62,6 @@ func (l *ListenerCounter) Inc() int64 {
// Dec decrements by 1 a current number of listeners. An error will occur if // Dec decrements by 1 a current number of listeners. An error will occur if
// a resulting number is less than 0. // a resulting number is less than 0.
func (l *ListenerCounter) Dec() (int64, error) { func (l *ListenerCounter) Dec() (int64, error) {
l.mutex.Lock()
defer l.mutex.Unlock()
if l.current == 0 { if l.current == 0 {
return l.current, errors.New("an attempt to decrement a number of current listeners down to less than 0") return l.current, errors.New("an attempt to decrement a number of current listeners down to less than 0")
} }
@ -84,8 +72,6 @@ func (l *ListenerCounter) Dec() (int64, error) {
// Reset current peak and overall listeners for a song that is playing. // Reset current peak and overall listeners for a song that is playing.
// And return its values. // And return its values.
func (l *ListenerCounter) Reset() (overall, peak int64) { func (l *ListenerCounter) Reset() (overall, peak int64) {
l.mutex.Lock()
defer l.mutex.Unlock()
peak = l.cur_peak peak = l.cur_peak
l.cur_peak = l.current l.cur_peak = l.current
overall = l.overall overall = l.overall
@ -94,8 +80,6 @@ func (l *ListenerCounter) Reset() (overall, peak int64) {
} }
func (l *ListenerCounter) MarshalJSON() ([]byte, error) { func (l *ListenerCounter) MarshalJSON() ([]byte, error) {
l.mutex.RLock()
defer l.mutex.RUnlock()
return json.Marshal(&struct { return json.Marshal(&struct {
Current int64 `json:"current"` Current int64 `json:"current"`
Peak int64 `json:"peak"` Peak int64 `json:"peak"`