Skip to content

Commit 4160dc1

Browse files
committed
correctly handle empty files on upload
1 parent 10c649f commit 4160dc1

File tree

5 files changed

+21
-10
lines changed

5 files changed

+21
-10
lines changed

internal/client/files-uploading.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,17 @@ func uploadFileByChunks(stream pb.CompilationService_UploadFileStreamClient, chu
132132
defer fd.Close()
133133

134134
var n int
135+
var sentChunks = 0 // used to correctly handle empty files (when Read returns EOF immediately)
135136
for {
136137
n, err = fd.Read(chunkBuf)
137-
if err == io.EOF {
138-
break
139-
}
140-
if err != nil {
138+
if err != nil && err != io.EOF {
141139
return err
142140
}
141+
if err == io.EOF && sentChunks != 0 {
142+
break
143+
}
144+
sentChunks++
145+
143146
err = stream.Send(&pb.UploadFileChunkRequest{
144147
ClientID: clientID,
145148
SessionID: sessionID,

internal/client/invocation.go

+11-5
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ type Invocation struct {
3434
cxxIDirs IncludeDirs // -I / -iquote / -isystem go here
3535
depsFlags DepCmdFlags // -MD -MF file and others, used for .d files generation (not passed to server)
3636

37-
doneState int32 // see Invocation.DoneRecvObj
38-
wgUpload sync.WaitGroup
39-
wgRecv sync.WaitGroup
37+
waitUploads int32 // files still waiting for upload to finish; 0 releases wgUpload; see Invocation.DoneUploadFile
38+
doneRecv int32 // 1 if o file received or failed receiving; 1 releases wgRecv; see Invocation.DoneRecvObj
39+
wgUpload sync.WaitGroup
40+
wgRecv sync.WaitGroup
4041

4142
// when remote compilation starts, the server starts a server.Session (with the same sessionID)
4243
// after it finishes, we have these fields filled (and objOutFile saved)
@@ -232,7 +233,7 @@ func (invocation *Invocation) CollectDependentIncludes(disableOwnIncludes bool)
232233
}
233234

234235
func (invocation *Invocation) DoneRecvObj(err error) {
235-
if atomic.SwapInt32(&invocation.doneState, 1) == 0 {
236+
if atomic.SwapInt32(&invocation.doneRecv, 1) == 0 {
236237
if err != nil {
237238
invocation.err = err
238239
}
@@ -244,11 +245,16 @@ func (invocation *Invocation) DoneUploadFile(err error) {
244245
if err != nil {
245246
invocation.err = err
246247
}
248+
atomic.AddInt32(&invocation.waitUploads, -1)
247249
invocation.wgUpload.Done() // will end up after all required files uploaded/failed
248250
}
249251

250252
func (invocation *Invocation) ForceInterrupt(err error) {
251-
// hopefully, an invocation can't hang on uploading files, it could hang only on waiting for obj
252253
logClient.Error("force interrupt", "sessionID", invocation.sessionID, invocation.cppInFile, err)
254+
// release invocation.wgUpload
255+
for atomic.LoadInt32(&invocation.waitUploads) != 0 {
256+
invocation.DoneUploadFile(err)
257+
}
258+
// release invocation.wgDone
253259
invocation.DoneRecvObj(err)
254260
}

internal/client/remote-connection.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ func (remote *RemoteConnection) StartCompilationSession(invocation *Invocation,
101101

102102
// UploadFilesToRemote uploads files to the remote in parallel and finishes after all of them are done.
103103
func (remote *RemoteConnection) UploadFilesToRemote(invocation *Invocation, requiredFiles []*pb.FileMetadata, fileIndexesToUpload []uint32) error {
104-
invocation.wgUpload.Add(len(fileIndexesToUpload))
104+
invocation.waitUploads = int32(len(fileIndexesToUpload))
105+
invocation.wgUpload.Add(int(invocation.waitUploads))
105106

106107
for _, fileIndex := range fileIndexesToUpload {
107108
remote.filesUploading.StartUploadingFileToRemote(invocation, requiredFiles[fileIndex], fileIndex)

tests/dt/cmake1/src/empty.h

Whitespace-only changes.

tests/dt/cmake1/src/main.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// main.cpp
22
#include "all-headers.h"
3+
#include "empty.h"
34

45
int main() {
56
std::cout << sum(1, 2) << std::endl;

0 commit comments

Comments
 (0)