Skip to content

Instantly share code, notes, and snippets.

@muhlemmer
Last active February 15, 2020 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muhlemmer/6afde02aeb195dae74e6e78365f18b03 to your computer and use it in GitHub Desktop.
Save muhlemmer/6afde02aeb195dae74e6e78365f18b03 to your computer and use it in GitHub Desktop.
package main
import (
"errors"
"fmt"
"sync"
"time"
)
type clientSession struct {
m sync.RWMutex
open bool
}
func (s *clientSession) Run() error {
s.m.Lock()
s.open = true
s.m.Unlock()
for {
s.m.RLock()
o := s.open
s.m.RUnlock()
if !o {
return errors.New("Run() closed")
}
}
}
func (s *clientSession) Close() {
s.m.Lock()
s.open = false
s.m.Unlock()
}
func main() {
var wg sync.WaitGroup // This is only added for demonstration purposes
s := new(clientSession)
r := make(chan error, 1)
go func(s *clientSession) {
wg.Add(1)
r <- s.Run()
wg.Done() // Will only be called after s.Run() is able to return
}(s)
fmt.Println("Client has been opened")
select {
case err := <-r:
fmt.Println(err)
case <-time.After(1 * time.Second):
s.Close()
fmt.Println("Timed out, closing")
}
wg.Wait() // Waits until wg.Done() is called.
fmt.Println("Main finished successfully")
}
package main
import (
"errors"
"fmt"
"sync"
"time"
)
type clientSession struct {
m sync.RWMutex
open bool
}
func (s *clientSession) Run() error {
s.m.Lock()
s.open = true
s.m.Unlock()
for {
s.m.RLock()
o := s.open
s.m.RUnlock()
if !o {
return errors.New("Run() closed")
}
}
}
func (s *clientSession) Close() {
s.m.Lock()
s.open = false
s.m.Unlock()
}
func main() {
var wg sync.WaitGroup // This is only added for demonstration purposes
s := new(clientSession)
r := make(chan error)
go func(s *clientSession) {
wg.Add(1)
r <- s.Run()
wg.Done() // Will only be called after s.Run() is able to return
}(s)
fmt.Println("Client has been opened")
X:
for {
select {
case err := <-r:
fmt.Println(err)
break X // because we are in main(). Normally `return err`
case <-time.After(1 * time.Second):
s.Close()
fmt.Println("Timed out, closing")
}
}
wg.Wait() // Waits until wg.Done() is called.
fmt.Println("Main finished successfully")
}
package main
import (
"errors"
"fmt"
"sync"
"time"
)
type clientSession struct {
m sync.RWMutex
open bool
}
func (s *clientSession) Run() error {
s.m.Lock()
s.open = true
s.m.Unlock()
for {
s.m.RLock()
o := s.open
s.m.RUnlock()
if !o {
return errors.New("Run() closed")
}
}
}
func (s *clientSession) Close() {
s.m.Lock()
s.open = false
s.m.Unlock()
}
func main() {
var wg sync.WaitGroup // This is only added for demonstration purposes
s := new(clientSession)
r := make(chan error)
go func(s *clientSession) {
wg.Add(1)
r <- s.Run()
wg.Done() // Will only be called after s.Run() is able to return
}(s)
fmt.Println("Client has been opened")
select {
case err := <-r:
fmt.Println(err)
case <-time.After(1 * time.Second):
s.Close()
fmt.Println("Timed out, closing")
}
wg.Wait() // Waits until wg.Done() is called.
fmt.Println("Main finished successfully")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment