Reputation: 678
I have an interface called Setter. Struct called SetterImpl implements this interface and has 2 setters, all of which set 2 interfaces.
type Setter interface {
A() *AInterface
B() *BInterface
}
type SetterImpl struct {
a *AInterface
b *BInterface
}
func (s *SetterImpl) A(a *AInterface) {
a = a
}
func (s *SetterImpl) B(b *AInterface) {
b = b
}
func returnSetter(a *AInterface, b *BInterface) Setter {
return &SetterImpl{a:a, b:b}
}
The setter returned by the above method is in heap(say SHeap) and sent to gRPC server. Now, I want to update a and b within the SetterImpl such that the gRPC server uses the new values.
So I have 2 goroutines now; one is gRPC server main goroutine(say MAIN), another is a forked one(say FORKED) which simply is to update the setter fields.
If I use Mutex in FORKED, that is essentially adding a fence (like java). It does not lock any variables actually(except itself). I do not want MAIN to be able to read a and b stored in SHeap while FORKED updates them. The API threads(goroutines) in the server do not acquire Read Mutex before reading values in SHeap. So, is it even possible to do what I am trying to achieve? If yes, how do I achieve this?
Upvotes: 0
Views: 1041
Reputation: 678
Variables can't be locked. So what I am trying to do is not possible.
The work-around I did was to add a RWMutex
into SetterImpl and doing
mux.RLock()
defer mux.RUnlock()
in getters of a and b in SetterImpl. And when I want to set a and b in FORKED, I used
mux.Lock()
defer mux.Unlock()
This way, if a write lock is acquired by FORKED, no read lock can be acquired at that time. This is possible as the RWLock field created in SHeap is used as global variable (i.e. this mutex is never changed and passed along FORKED)
Upvotes: 0
Reputation: 778
I don't think you can lock variables in Go. You can only lock a code section.
m.Lock()
// do stuff
m.Unlock()
You are creating a problem for yourself out of nothing by using the "interface" vs "Impl" pattern.
You can make your life simpler by just using a regular function. Then you can put the lock inside a function and be guaranteed that it will be protected.
Since you are making an interface, you can't guarantee anything about the content of the function that implements the interface.
Upvotes: 1