Skip to content

adds Close() method to Input and Output interfaces#19

Open
rafaelvanoni wants to merge 13 commits into
masterfrom
cgo-segfault
Open

adds Close() method to Input and Output interfaces#19
rafaelvanoni wants to merge 13 commits into
masterfrom
cgo-segfault

Conversation

@rafaelvanoni

Copy link
Copy Markdown
Contributor

Once the fix in farsightsec/nmsg#195 was in place, I ran into several small issues in the go-nmsg unit tests. This MR proposes such fixes.

@rafaelvanoni
rafaelvanoni requested review from cmikk and shw700 July 10, 2026 17:52
@rafaelvanoni rafaelvanoni self-assigned this Jul 10, 2026
Comment thread go.sum Outdated

@cmikk cmikk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This MR fixes a lot of various things. For the purposes of maintaining a useful git history, these fixes should be documented in commit titles and descriptions. I've made a few suggestions of breakdowns, and a few other fixes in comments.

Comment thread cgo-nmsg/container.go Outdated
co.c.config.Compress = compress
}

// Close flushes any buffered output and satisfies the interface

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should specify "satisfies the Output interface"

Comment thread cgo-nmsg/input.go Outdated
// Read calls the underlying function to return the next message.
func (i InputFunc) Read() (*Message, error) { return i() }

// Closes satisfies the interface with a no-op

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should specify "satisfies the Input interface with a no-op"

Comment thread cgo-nmsg/output.go Outdated
// Write calls the underlying function with the supplied message
func (o OutputFunc) Write(m *Message) error { return o(m) }

// Close satisfies the interface with a no-op

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should specify "satisfies the Output interface with a no-op"

Comment thread cgo-nmsg/input.go
// Read returns a Message or nil, and an error if any.
Read() (*Message, error)

// Closes and releases the input's resources.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The additions of the Close() method to the Input and Output interfaces and their implementations are a logically separate change and should be in its own commit, possibly along with the explicit calls to these new Close()s in the go-nmsg tests.

(The current commit description of "cgo-nmsg sometimes segfaults..." also does not match the changes.)

Comment thread cgo-nmsg/zmq.go
}
return &nmsgOutput{output: outp}, nil
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change to the cgo-nmsg zmq API should be handled as a separate commit, if not as a separate issue with possibly-breaking[1] API changes on the table.

The original code (mine) is kind of odd in this respect; I most likely chose this "global singleton zmq_ctx" pattern to save the caller from:

  1. separately linking against the C zmq library, and
  2. maintaining and passing an unsafe.Pointer (void * in the C zmq API) value

A different approach would be to expose / re-expose a zmq context API from cgo-nmsg, wrapping the zmq_ctx in a proper type, and requiring that argument to NewZMQOutput / NewZMQInput, which would be more in line with C nmsg API. Either this, the exposed unsafe.Pointer / separate linking approach would be valid alternatives to the current "let the singleton zmqContext be dropped at shutdown" approach.

FWIW, it appears that nmsgtool in the C distribution does the latter -- there are no calls to zmq_ctx_destroy or the more modern zmq_ctx_term in the nmsg distribution outside of tests.

[1] To the best of my knowledge, this cgo-nmsg code is only used within test cases in go-nmsg, as the cgo overhead is (or at least was) significant enough to prohibit most nmsg processing use cases. Thus, breaking changes are acceptable, as is living with suboptimal API features so long as they don't compromise test cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be ok to include these two changes (zmq_ctx_new() and zmq_ctx_term()) now and introduce new APIs in a follow up?

Comment thread output_test.go
p, err := nmsg.Payload(testMessage(1000))
if err != nil {
t.Errorf(err.Error())
t.Error(err.Error())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These Errorf -> Error substitutions should be separately committed.

Comment thread sockspec_test.go
{"127.0.0.1/foobar", false, 0},
{"127.0.0.1/390..382", false, 0},
{"127.0.0.1/390..foobar", false, 0},
{"invalid_hostname/381", false, 0},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this test case removed?

The other change to this file appears purely stylistic / formatting. What was its source?

(In other projects, we're discussing standardizing on stability under the standard go fmt for simplicity.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted these

Comment thread zmq.go Outdated
return "", sockdirInvalid, SocktypeInvalid, errors.New("socket type is already set")
}
socktype = SocktypePushpull
default:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the C library equivalent to this function (also named munge_endpoint) ignores unknown tokens. We can either leave this out for consistency or also fix the issue there (perhaps along with the lack of zmq_term in nmsgtool.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted this one too

Comment thread zmq.go
return nil, err
}
binded = true
bound = true

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit has several changes to the zmq implementation mixed together. On review, I can see:

  • closing sockets on error
  • disconnecting connected sockets on close, not just bind
  • checking for Read() truncation, and
  • the editory binded -> bound

These, and any I missed, should be documented in one or more commit descriptions.

Comment thread zmq_test.go Outdated
if mod == nil {
log.Fatal("module not found")
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with the previous file (zmq.go), this commit mixes several changes to this file, including:

  • whitespace changes
  • Adding defer x.Close() cleanup for inputs and outputs, which could be grouped with the cgo-nmsg Close() method addition. and
  • adding channel synchronization to test goroutines, which is a substantive fix and should be its own commit, or at the very least documented in a commit

@rafaelvanoni

Copy link
Copy Markdown
Contributor Author

@cmikk I repaved this PR with commit-separated changes, sorry for the initial mess.

@rafaelvanoni rafaelvanoni changed the title cgo-nmsg sometimes segfaults during automated package build/testing adds Close() method to Input and Output interfaces Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants