Susumu Yata
null+****@clear*****
Thu Feb 18 13:07:49 JST 2016
Susumu Yata 2016-02-18 13:07:49 +0900 (Thu, 18 Feb 2016) New Revision: 8da9f300130ca30d9f5da897d36b5513c297f8a9 https://github.com/groonga/grnci/commit/8da9f300130ca30d9f5da897d36b5513c297f8a9 Message: Add GrnInit, GrnFin and DisableGrnInit GitHub: #32 Modified files: grn.go Modified: grn.go (+75 -13) =================================================================== --- grn.go 2016-02-18 12:15:52 +0900 (0c595d3) +++ grn.go 2016-02-18 13:07:49 +0900 (e01e5b1) @@ -16,9 +16,10 @@ import ( // Groonga. // // C.grn_init initializes Groonga and C.grn_fin finalizes Groonga. -// Note that C.grn_init() must not be called if Groonga is already initialized. +// Note that C.grn_init must not be called if Groonga is already initialized. // -// Grnci automatically initializes Groonga when it creates a new DB instance. +// Grnci, by default, initializes Groonga when it creates the first DB +// instance. // To achieve this, Grnci uses a reference count. // grnCnt is a reference count for Groonga. @@ -28,37 +29,98 @@ var grnCnt uint32 // grnCntMutex is a mutex for grnCnt. var grnCntMutex sync.Mutex -// grnInit increments grnCnt and initializes Groonga if grnCnt changes from 0 -// to 1. +// grnInitLib initializes Groonga. +func grnInitLib() error { + if rc := C.grn_init(); rc != C.GRN_SUCCESS { + return fmt.Errorf("grn_init failed: rc = %s", rc) + } + C.grnci_init_thread_limit() + return nil +} + +// grnFinLib finalizes Groonga. +func grnFinLib() error { + if rc := C.grn_fin(); rc != C.GRN_SUCCESS { + return fmt.Errorf("grn_fin failed: rc = %s", rc) + } + return nil +} + +// grnInit increments grnCnt and initializes Groonga if it changes from 0 to 1. func grnInit() error { grnCntMutex.Lock() defer grnCntMutex.Unlock() if grnCnt == math.MaxUint32 { - return fmt.Errorf("grnCnt overflow") + return fmt.Errorf("grnCnt = %d", grnCnt) } if grnCnt == 0 { - if rc := C.grn_init(); rc != C.GRN_SUCCESS { - return fmt.Errorf("grn_init() failed: rc = %s", rc) + if err := grnInitLib(); err != nil { + return err } - C.grnci_init_thread_limit() } grnCnt++ return nil } -// grnFin decrements grnCnt and initializes Groonga if grnCnt changes from 1 -// to 0. +// grnFin decrements grnCnt and finalizes Groonga if it changes from 1 to 0. func grnFin() error { grnCntMutex.Lock() defer grnCntMutex.Unlock() if grnCnt == 0 { - return fmt.Errorf("grnCnt underflow") + return fmt.Errorf("grnCnt = %d", grnCnt) } grnCnt-- if grnCnt == 0 { - if rc := C.grn_fin(); rc != C.GRN_SUCCESS { - return fmt.Errorf("grn_fin() failed: rc = %s", rc) + if err := grnFinLib(); err != nil { + return err } } return nil } + +// GrnInit explicitly initializes Groonga. +// GrnInit should not be called if Groonga is already initialized. +// +// Note that Groonga is implicitly initialized when Grnci creates the first DB +// instance. +func GrnInit() error { + grnCntMutex.Lock() + defer grnCntMutex.Unlock() + if grnCnt != 0 { + return fmt.Errorf("grnCnt = %d", grnCnt) + } + if err := grnInitLib(); err != nil { + return err + } + grnCnt++ + return nil +} + +// GrnFin explicitly finalizes Groonga. +// GrnFin should be used if Groonga is initialized by GrnInit. +// +// Note that Groonga is implicitly finalized when Grnci deletes the last DB +// instance if GrnInit is not used. +func GrnFin() error { + grnCntMutex.Lock() + defer grnCntMutex.Unlock() + if grnCnt == 0 { + return fmt.Errorf("grnCnt = %d", grnCnt) + } else if grnCnt != 1 { + return fmt.Errorf("grnCnt = %d", grnCnt) + } + grnCnt-- + return grnFinLib() +} + +// DisableGrnInit disables implicit Groonga initialization and finalization. +// DisableGrnInit should be called before creating the first DB instance. +func DisableGrnInit() error { + grnCntMutex.Lock() + defer grnCntMutex.Unlock() + if grnCnt != 0 { + return fmt.Errorf("grnCnt = %d", grnCnt) + } + grnCnt++ + return nil +} -------------- next part -------------- HTML����������������������������...Download