Fix race conditions using Anko.

This commit is contained in:
Leonel Quinteros
2016-07-15 19:46:17 -03:00
parent 74daa24696
commit 653444ba98

21
po.go
View File

@@ -3,7 +3,7 @@ package gotext
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"github.com/mattn/anko/vm" "github.com/leonelquinteros/anko/vm"
"io/ioutil" "io/ioutil"
"net/textproto" "net/textproto"
"os" "os"
@@ -112,12 +112,14 @@ func (po *Po) ParseFile(f string) {
// Parse loads the translations specified in the provided string (str) // Parse loads the translations specified in the provided string (str)
func (po *Po) Parse(str string) { func (po *Po) Parse(str string) {
// Lock while parsing
po.Lock()
defer po.Unlock()
// Init storage // Init storage
if po.translations == nil { if po.translations == nil {
po.Lock()
po.translations = make(map[string]*translation) po.translations = make(map[string]*translation)
po.contexts = make(map[string]map[string]*translation) po.contexts = make(map[string]map[string]*translation)
po.Unlock()
} }
// Get lines // Get lines
@@ -146,7 +148,6 @@ func (po *Po) Parse(str string) {
// Buffer context and continue // Buffer context and continue
if strings.HasPrefix(l, "msgctxt") { if strings.HasPrefix(l, "msgctxt") {
// Save current translation buffer. // Save current translation buffer.
po.Lock()
// No context // No context
if ctx == "" { if ctx == "" {
po.translations[tr.id] = tr po.translations[tr.id] = tr
@@ -157,7 +158,6 @@ func (po *Po) Parse(str string) {
} }
po.contexts[ctx][tr.id] = tr po.contexts[ctx][tr.id] = tr
} }
po.Unlock()
// Flush buffer // Flush buffer
tr = newTranslation() tr = newTranslation()
@@ -174,9 +174,7 @@ func (po *Po) Parse(str string) {
if strings.HasPrefix(l, "msgid") && !strings.HasPrefix(l, "msgid_plural") { if strings.HasPrefix(l, "msgid") && !strings.HasPrefix(l, "msgid_plural") {
// Save current translation buffer if not inside a context. // Save current translation buffer if not inside a context.
if ctx == "" { if ctx == "" {
po.Lock()
po.translations[tr.id] = tr po.translations[tr.id] = tr
po.Unlock()
// Flush buffer // Flush buffer
tr = newTranslation() tr = newTranslation()
@@ -266,7 +264,6 @@ func (po *Po) Parse(str string) {
// Save last translation buffer. // Save last translation buffer.
if tr.id != "" { if tr.id != "" {
po.Lock()
if ctx == "" { if ctx == "" {
po.translations[tr.id] = tr po.translations[tr.id] = tr
} else { } else {
@@ -276,11 +273,11 @@ func (po *Po) Parse(str string) {
} }
po.contexts[ctx][tr.id] = tr po.contexts[ctx][tr.id] = tr
} }
po.Unlock()
} }
// Parse headers // Parse headers
po.RawHeaders += "\n\n" po.RawHeaders += "\n\n"
reader := bufio.NewReader(strings.NewReader(po.RawHeaders)) reader := bufio.NewReader(strings.NewReader(po.RawHeaders))
tp := textproto.NewReader(reader) tp := textproto.NewReader(reader)
@@ -321,6 +318,9 @@ func (po *Po) Parse(str string) {
// pluralForm calculates the plural form index corresponding to n. // pluralForm calculates the plural form index corresponding to n.
// Returns 0 on error // Returns 0 on error
func (po *Po) pluralForm(n int) int { func (po *Po) pluralForm(n int) int {
po.RLock()
defer po.RUnlock()
// Failsafe // Failsafe
if po.nplurals < 1 { if po.nplurals < 1 {
return 0 return 0
@@ -330,10 +330,9 @@ func (po *Po) pluralForm(n int) int {
} }
// Init compiler // Init compiler
var env = vm.NewEnv() env := vm.NewEnv()
env.Define("n", n) env.Define("n", n)
// Run script
plural, err := env.Execute(po.plural) plural, err := env.Execute(po.plural)
if err != nil { if err != nil {
return 0 return 0