Skip to content

Commit 6941ccc

Browse files
committed
Merge branch 'master' into next
2 parents ac719c6 + fa644d2 commit 6941ccc

File tree

1 file changed

+15
-41
lines changed

1 file changed

+15
-41
lines changed

handles.go

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package git
22

3+
/*
4+
#include <stdlib.h>
5+
*/
6+
import "C"
37
import (
48
"fmt"
59
"sync"
@@ -9,75 +13,45 @@ import (
913
type HandleList struct {
1014
sync.RWMutex
1115
// stores the Go pointers
12-
handles []interface{}
13-
// Indicates which indices are in use.
14-
set map[int]bool
16+
handles map[unsafe.Pointer]interface{}
1517
}
1618

1719
func NewHandleList() *HandleList {
1820
return &HandleList{
19-
handles: make([]interface{}, 5),
20-
set: make(map[int]bool),
21+
handles: make(map[unsafe.Pointer]interface{}),
2122
}
2223
}
2324

24-
// findUnusedSlot finds the smallest-index empty space in our
25-
// list. You must only run this function while holding a write lock.
26-
func (v *HandleList) findUnusedSlot() int {
27-
for i := 1; i < len(v.handles); i++ {
28-
if !v.set[i] {
29-
return i
30-
}
31-
}
32-
33-
// reaching here means we've run out of entries so append and
34-
// return the new index, which is equal to the old length.
35-
slot := len(v.handles)
36-
v.handles = append(v.handles, nil)
37-
38-
return slot
39-
}
40-
4125
// Track adds the given pointer to the list of pointers to track and
4226
// returns a pointer value which can be passed to C as an opaque
4327
// pointer.
4428
func (v *HandleList) Track(pointer interface{}) unsafe.Pointer {
45-
v.Lock()
46-
47-
slot := v.findUnusedSlot()
48-
v.handles[slot] = pointer
49-
v.set[slot] = true
29+
handle := C.malloc(1)
5030

31+
v.Lock()
32+
v.handles[handle] = pointer
5133
v.Unlock()
5234

53-
return unsafe.Pointer(uintptr(slot))
35+
return handle
5436
}
5537

5638
// Untrack stops tracking the pointer given by the handle
5739
func (v *HandleList) Untrack(handle unsafe.Pointer) {
58-
slot := int(uintptr(handle))
59-
6040
v.Lock()
61-
62-
v.handles[slot] = nil
63-
delete(v.set, slot)
64-
41+
delete(v.handles, handle)
42+
C.free(handle)
6543
v.Unlock()
6644
}
6745

6846
// Get retrieves the pointer from the given handle
6947
func (v *HandleList) Get(handle unsafe.Pointer) interface{} {
70-
slot := int(uintptr(handle))
71-
7248
v.RLock()
49+
defer v.RUnlock()
7350

74-
if !v.set[slot] {
51+
ptr, ok := v.handles[handle]
52+
if !ok {
7553
panic(fmt.Sprintf("invalid pointer handle: %p", handle))
7654
}
7755

78-
ptr := v.handles[slot]
79-
80-
v.RUnlock()
81-
8256
return ptr
8357
}

0 commit comments

Comments
 (0)