Skip to content

Commit 01d1a5c

Browse files
author
Vicent Martí
committed
Merge pull request libgit2#24 from carlosmn/packbuilder-abort
Allow aborting the pack writing operation
2 parents 0942474 + b189d79 commit 01d1a5c

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

packbuilder.go

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,11 @@ func (pb *Packbuilder) WriteToFile(name string) error {
7676
}
7777

7878
func (pb *Packbuilder) Write(w io.Writer) error {
79-
ch := pb.ForEach()
79+
ch, stop := pb.ForEach()
8080
for slice := range ch {
8181
_, err := w.Write(slice)
8282
if err != nil {
83+
close(stop)
8384
return err
8485
}
8586
}
@@ -90,22 +91,40 @@ func (pb *Packbuilder) Written() uint32 {
9091
return uint32(C.git_packbuilder_written(pb.ptr))
9192
}
9293

94+
type packbuilderCbData struct {
95+
ch chan<- []byte
96+
stop <-chan bool
97+
}
98+
9399
//export packbuilderForEachCb
94100
func packbuilderForEachCb(buf unsafe.Pointer, size C.size_t, payload unsafe.Pointer) int {
95-
ch := *(*chan []byte)(payload)
101+
data := (*packbuilderCbData)(payload)
102+
ch := data.ch
103+
stop := data.stop
96104

97105
slice := C.GoBytes(buf, C.int(size))
98-
ch <- slice
106+
select {
107+
case <- stop:
108+
return -1
109+
case ch <- slice:
110+
}
111+
99112
return 0
100113
}
101114

102-
func (pb *Packbuilder) forEachWrap(ch chan []byte) {
103-
C._go_git_packbuilder_foreach(pb.ptr, unsafe.Pointer(&ch))
104-
close(ch)
115+
func (pb *Packbuilder) forEachWrap(data *packbuilderCbData) {
116+
C._go_git_packbuilder_foreach(pb.ptr, unsafe.Pointer(data))
117+
close(data.ch)
105118
}
106119

107-
func (pb *Packbuilder) ForEach() chan []byte {
108-
ch := make(chan []byte, 0)
109-
go pb.forEachWrap(ch)
110-
return ch
120+
// Foreach sends the packfile as slices through the "data" channel. If
121+
// you want to stop the pack-building process (e.g. there's an error
122+
// writing to the output), close or write a value into the "stop"
123+
// channel.
124+
func (pb *Packbuilder) ForEach() (data <-chan []byte, stop chan<- bool) {
125+
ch := make(chan []byte)
126+
stop := make(chan bool)
127+
data := packbuilderCbData{ch, stop}
128+
go pb.forEachWrap(&data)
129+
return ch, stop
111130
}

0 commit comments

Comments
 (0)