From c848278690009136fa7456ce4af57fea31b3886d Mon Sep 17 00:00:00 2001 From: hackerchai Date: Fri, 2 Aug 2024 17:48:19 +0800 Subject: [PATCH 1/9] feat(c/libuv): Add uv_close & uv_signal func Signed-off-by: hackerchai feat(c/libuv): Add uv_signal_stop func Signed-off-by: hackerchai feat(c/libuv): Add GetIoWatcher, GetFd func & add Io srtuct Signed-off-by: hackerchai refactor(c/libuv): Rename some func refactor(c/libuv): Remove net go wrapper refactor(c/libuv): Add GetIoWatcherFd func --- c/libuv/libuv.go | 3 +++ c/libuv/signal.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/c/libuv/libuv.go b/c/libuv/libuv.go index b567bedc..e7c4e0f2 100644 --- a/c/libuv/libuv.go +++ b/c/libuv/libuv.go @@ -158,6 +158,9 @@ func LibraryShutdown() //go:linkname ReplaceAllocator C.uv_replace_allocator func ReplaceAllocator(mallocFunc MallocFunc, reallocFunc ReallocFunc, callocFunc CallocFunc, freeFunc FreeFunc) c.Int +//go:linkname Close C.uv_close +func Close(handle *Handle, closeCb CloseCb) + // ---------------------------------------------- // llgo:link (*Shutdown).Shutdown C.uv_shutdown diff --git a/c/libuv/signal.go b/c/libuv/signal.go index a3ede8ff..bf8735d1 100644 --- a/c/libuv/signal.go +++ b/c/libuv/signal.go @@ -31,3 +31,6 @@ func SignalStart(handle *Signal, cb SignalCb, signum c.Int) c.Int //go:linkname SignalStartOneshot C.uv_signal_start_oneshot func SignalStartOneshot(handle *Signal, cb SignalCb, signum c.Int) c.Int + +//go:linkname SignalStop C.uv_signal_stop +func SignalStop(handle *Signal) c.Int From 5d0a91239c6344c15f77e6ff39fef60436297736 Mon Sep 17 00:00:00 2001 From: hackerchai Date: Tue, 6 Aug 2024 11:54:28 +0800 Subject: [PATCH 2/9] feat(c/libuv): Add GetIoWatcherFd func --- c/libuv/net.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/c/libuv/net.go b/c/libuv/net.go index 2463666c..8026c3a6 100644 --- a/c/libuv/net.go +++ b/c/libuv/net.go @@ -1,5 +1,9 @@ package libuv +//#cgo pkg-config: libuv +//#include +import "C" + import ( _ "unsafe" @@ -65,23 +69,19 @@ type UdpFlags c.Int /* Handle types. */ +type Tcp C.uv_tcp_t // TODO(spongehah): Handle type Handle struct { Data c.Pointer Unused [88]byte +// TODO(spongehah): Stream } -// TODO(spongehah): Stream type Stream struct { Data c.Pointer Unused [256]byte } -// TODO(spongehah): Tcp -type Tcp struct { - Data c.Pointer - Unused [256]byte -} type Udp struct { Unused [0]byte @@ -97,17 +97,17 @@ type UdpSend struct { Unused [0]byte } -// TODO(spongehah): Write -type Write struct { - Data c.Pointer - Unused [184]byte -} // TODO(spongehah): Connect type Connect struct { Data c.Pointer Unused [88]byte } +// TODO(spongehah): Write +type Write struct { + Data c.Pointer + Unused [184]byte +} type GetAddrInfo struct { Unused [0]byte @@ -359,6 +359,11 @@ func (tcp *Tcp) CloseReset(closeCb CloseCb) c.Int { //go:linkname TcpConnect C.uv_tcp_connect func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int +func (tcp *Tcp) GetIoWatcherFd() c.Int { + tcp_s := (*C.uv_tcp_t)(c.Pointer(tcp)) + return c.Int(tcp_s.io_watcher.fd) +} + // ---------------------------------------------- /* Udp related function and method */ From 9b12e9819c99d91eba48f3309bff7464190cf112 Mon Sep 17 00:00:00 2001 From: hackerchai Date: Tue, 6 Aug 2024 14:32:30 +0800 Subject: [PATCH 3/9] fix(c/libuv/demo): Fix echo_server stream convert --- c/libuv/_demo/echo_server/echo_server.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/c/libuv/_demo/echo_server/echo_server.go b/c/libuv/_demo/echo_server/echo_server.go index 9d961200..2c9a71b8 100644 --- a/c/libuv/_demo/echo_server/echo_server.go +++ b/c/libuv/_demo/echo_server/echo_server.go @@ -31,7 +31,7 @@ func main() { // Bind the server to the specified address and port (&server).Bind((*net.SockAddr)(c.Pointer(&addr)), 0) - res := (*libuv.Stream)(&server).Listen(DEFAULT_BACKLOG, OnNewConnection) + res := (*libuv.Stream)(unsafe.Pointer(&server)).Listen(DEFAULT_BACKLOG, OnNewConnection) if res != 0 { c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror((libuv.Errno(res)))) return @@ -110,8 +110,8 @@ func OnNewConnection(server *libuv.Stream, status c.Int) { } // Accept the new connection and start reading data. - if server.Accept((*libuv.Stream)(client)) == 0 { - (*libuv.Stream)(client).StartRead(AllocBuffer, EchoRead) + if server.Accept((*libuv.Stream)(unsafe.Pointer(client))) == 0 { + (*libuv.Stream)(unsafe.Pointer(client)).StartRead(AllocBuffer, EchoRead) } else { (*libuv.Handle)(c.Pointer(client)).Close(nil) } From 9a61e374b56d055230c96f69cffab3cb5246dbe1 Mon Sep 17 00:00:00 2001 From: hackerchai Date: Tue, 6 Aug 2024 15:58:15 +0800 Subject: [PATCH 4/9] refactor(c/libuv): Move some func due to libuv doc doc: https://docs.libuv.org/en/v1.x/ --- c/libuv/libuv.go | 37 ++++++++++--------------------------- c/libuv/net.go | 26 ++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/c/libuv/libuv.go b/c/libuv/libuv.go index e7c4e0f2..6a5e826c 100644 --- a/c/libuv/libuv.go +++ b/c/libuv/libuv.go @@ -103,10 +103,6 @@ type Poll struct { /* Request types. */ -type Shutdown struct { - Unused [0]byte -} - type Buf struct { Base *c.Char Len uintptr @@ -135,9 +131,6 @@ type GetaddrinfoCb func(req *GetAddrInfo, status c.Int, res *net.AddrInfo) // llgo:type C type GetnameinfoCb func(req *GetNameInfo, status c.Int, hostname *c.Char, service *c.Char) -// llgo:type C -type ShutdownCb func(req *Shutdown, status c.Int) - // llgo:type C type WalkCb func(handle *Handle, arg c.Pointer) @@ -158,16 +151,6 @@ func LibraryShutdown() //go:linkname ReplaceAllocator C.uv_replace_allocator func ReplaceAllocator(mallocFunc MallocFunc, reallocFunc ReallocFunc, callocFunc CallocFunc, freeFunc FreeFunc) c.Int -//go:linkname Close C.uv_close -func Close(handle *Handle, closeCb CloseCb) - -// ---------------------------------------------- - -// llgo:link (*Shutdown).Shutdown C.uv_shutdown -func (shutdown *Shutdown) Shutdown(stream *Stream, shutdownCb ShutdownCb) c.Int { - return 0 -} - // ---------------------------------------------- /* Loop related functions and method. */ @@ -202,20 +185,20 @@ func LoopInit(loop *Loop) c.Int //go:linkname LoopNew C.uv_loop_new func LoopNew() *Loop -//go:linkname LoopNow C.uv_now -func LoopNow(loop *Loop) c.UlongLong +//go:linkname Now C.uv_now +func Now(loop *Loop) c.UlongLong -//go:linkname LoopUpdateTime C.uv_update_time -func LoopUpdateTime(loop *Loop) +//go:linkname UpdateTime C.uv_update_time +func UpdateTime(loop *Loop) -//go:linkname LoopBackendFd C.uv_backend_fd -func LoopBackendFd(loop *Loop) c.Int +//go:linkname BackendFd C.uv_backend_fd +func BackendFd(loop *Loop) c.Int -//go:linkname LoopBackendTimeout C.uv_backend_timeout -func LoopBackendTimeout(loop *Loop) c.Int +//go:linkname BackendTimeout C.uv_backend_timeout +func BackendTimeout(loop *Loop) c.Int -//go:linkname LoopWalk C.uv_walk -func LoopWalk(loop *Loop, walkCb WalkCb, arg c.Pointer) +//go:linkname Walk C.uv_walk +func Walk(loop *Loop, walkCb WalkCb, arg c.Pointer) // ---------------------------------------------- diff --git a/c/libuv/net.go b/c/libuv/net.go index 8026c3a6..c04e4705 100644 --- a/c/libuv/net.go +++ b/c/libuv/net.go @@ -70,11 +70,12 @@ type UdpFlags c.Int /* Handle types. */ type Tcp C.uv_tcp_t + // TODO(spongehah): Handle type Handle struct { Data c.Pointer Unused [88]byte -// TODO(spongehah): Stream + // TODO(spongehah): Stream } type Stream struct { @@ -82,6 +83,9 @@ type Stream struct { Unused [256]byte } +type Shutdown struct { + Unused [0]byte +} type Udp struct { Unused [0]byte @@ -97,12 +101,12 @@ type UdpSend struct { Unused [0]byte } - // TODO(spongehah): Connect type Connect struct { Data c.Pointer Unused [88]byte } + // TODO(spongehah): Write type Write struct { Data c.Pointer @@ -142,6 +146,9 @@ type WriteCb func(req *Write, status c.Int) // llgo:type C type ConnectionCb func(server *Stream, status c.Int) +// llgo:type C +type ShutdownCb func(req *Shutdown, status c.Int) + // ---------------------------------------------- /* Handle related function and method */ @@ -219,6 +226,16 @@ func (handle *Handle) IsClosing() c.Int { return 0 } +// llgo:link (*Handle).IsReadable C.uv_is_readable +func (handle *Handle) IsReadable() c.Int { + return 0 +} + +// llgo:link (*Handle).IsWritable C.uv_is_writable +func (handle *Handle) IsWritable() c.Int { + return 0 +} + // ---------------------------------------------- /* Req related function and method */ @@ -306,6 +323,11 @@ func (stream *Stream) SetBlocking(blocking c.Int) c.Int { return 0 } +//go:linkname StreamShutdown C.uv_shutdown +func StreamShutdown(shutdown *Shutdown, stream *Stream, shutdownCb ShutdownCb) c.Int { + return 0 +} + // ---------------------------------------------- /* Tcp related function and method */ From 26f8ce7b5a8f08fad6e37abcad07ea1621d13443 Mon Sep 17 00:00:00 2001 From: hackerchai Date: Tue, 6 Aug 2024 16:05:09 +0800 Subject: [PATCH 5/9] refactor(c/libuv): Use cgo alias replace struct assertion in fs refactro(c/libuv): Use cgo alias avoid implicit struct member declaration --- c/libuv/fs.go | 8 ++++-- c/libuv/net.go | 76 ++++++++++++++++++++------------------------------ 2 files changed, 36 insertions(+), 48 deletions(-) diff --git a/c/libuv/fs.go b/c/libuv/fs.go index 9bb8f57f..35152ffd 100644 --- a/c/libuv/fs.go +++ b/c/libuv/fs.go @@ -1,5 +1,9 @@ package libuv +//#cgo pkg-config: libuv +//#include +import "C" + import ( _ "unsafe" @@ -68,9 +72,7 @@ type File c.Int /* Handle types. */ -type Fs struct { - Unused [440]byte -} +type Fs C.uv_fs_t type FsEvent struct { Unused [0]byte diff --git a/c/libuv/net.go b/c/libuv/net.go index c04e4705..3ceb10f2 100644 --- a/c/libuv/net.go +++ b/c/libuv/net.go @@ -71,17 +71,9 @@ type UdpFlags c.Int type Tcp C.uv_tcp_t -// TODO(spongehah): Handle -type Handle struct { - Data c.Pointer - Unused [88]byte - // TODO(spongehah): Stream -} +type Handle C.uv_handle_t -type Stream struct { - Data c.Pointer - Unused [256]byte -} +type Stream C.uv_stream_t type Shutdown struct { Unused [0]byte @@ -101,17 +93,9 @@ type UdpSend struct { Unused [0]byte } -// TODO(spongehah): Connect -type Connect struct { - Data c.Pointer - Unused [88]byte -} +type Connect C.uv_connect_t -// TODO(spongehah): Write -type Write struct { - Data c.Pointer - Unused [184]byte -} +type Write C.uv_write_t type GetAddrInfo struct { Unused [0]byte @@ -153,6 +137,12 @@ type ShutdownCb func(req *Shutdown, status c.Int) /* Handle related function and method */ +//go:linkname HandleSize C.uv_handle_size +func HandleSize(handleType HandleType) uintptr + +//go:linkname HandleTypeName C.uv_handle_type_name +func HandleTypeName(handleType HandleType) *c.Char + // llgo:link (*Handle).Ref C.uv_ref func (handle *Handle) Ref() {} @@ -164,17 +154,11 @@ func (handle *Handle) HasRef() c.Int { return 0 } -//go:linkname HandleSize C.uv_handle_size -func HandleSize(handleType HandleType) uintptr - // llgo:link (*Handle).GetType C.uv_handle_get_type func (handle *Handle) GetType() HandleType { return 0 } -//go:linkname HandleTypeName C.uv_handle_type_name -func HandleTypeName(handleType HandleType) *c.Char - // llgo:link (*Handle).GetData C.uv_handle_get_data func (handle *Handle) GetData() c.Pointer { return nil @@ -211,16 +195,6 @@ func (handle *Handle) Fileno(fd *OsFd) c.Int { return 0 } -//go:linkname Pipe C.uv_pipe -func Pipe(fds [2]File, readFlags c.Int, writeFlags c.Int) c.Int { - return 0 -} - -//go:linkname Socketpair C.uv_socketpair -func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 c.Int, flag1 c.Int) c.Int { - return 0 -} - // llgo:link (*Handle).IsClosing C.uv_is_closing func (handle *Handle) IsClosing() c.Int { return 0 @@ -236,6 +210,16 @@ func (handle *Handle) IsWritable() c.Int { return 0 } +//go:linkname Pipe C.uv_pipe +func Pipe(fds [2]File, readFlags c.Int, writeFlags c.Int) c.Int { + return 0 +} + +//go:linkname Socketpair C.uv_socketpair +func Socketpair(_type c.Int, protocol c.Int, socketVector [2]OsSock, flag0 c.Int, flag1 c.Int) c.Int { + return 0 +} + // ---------------------------------------------- /* Req related function and method */ @@ -243,6 +227,9 @@ func (handle *Handle) IsWritable() c.Int { //go:linkname ReqSize C.uv_req_size func ReqSize(reqType ReqType) uintptr +//go:linkname TypeName C.uv_req_type_name +func TypeName(reqType ReqType) *c.Char + // llgo:link (*Req).GetData C.uv_req_get_data func (req *Req) GetData() c.Pointer { return nil @@ -256,9 +243,6 @@ func (req *Req) GetType() ReqType { return 0 } -//go:linkname TypeName C.uv_req_type_name -func TypeName(reqType ReqType) *c.Char - // ---------------------------------------------- /* Stream related function and method */ @@ -378,14 +362,14 @@ func (tcp *Tcp) CloseReset(closeCb CloseCb) c.Int { return 0 } -//go:linkname TcpConnect C.uv_tcp_connect -func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int - func (tcp *Tcp) GetIoWatcherFd() c.Int { tcp_s := (*C.uv_tcp_t)(c.Pointer(tcp)) return c.Int(tcp_s.io_watcher.fd) } +//go:linkname TcpConnect C.uv_tcp_connect +func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int + // ---------------------------------------------- /* Udp related function and method */ @@ -456,9 +440,6 @@ func (udp *Udp) SetTTL(ttl c.Int) c.Int { return 0 } -//go:linkname Send C.uv_udp_send -func Send(req *UdpSend, udp *Udp, bufs *Buf, nbufs c.Uint, addr *net.SockAddr, sendCb UdpSendCb) c.Int - // llgo:link (*Udp).TrySend C.uv_udp_try_send func (udp *Udp) TrySend(bufs *Buf, nbufs c.Uint, addr *net.SockAddr) c.Int { return 0 @@ -489,8 +470,13 @@ func (udp *Udp) GetSendQueueCount() uintptr { return 0 } +//go:linkname Send C.uv_udp_send +func Send(req *UdpSend, udp *Udp, bufs *Buf, nbufs c.Uint, addr *net.SockAddr, sendCb UdpSendCb) c.Int + // ---------------------------------------------- +/* DNS related function and method */ + //go:linkname Ip4Addr C.uv_ip4_addr func Ip4Addr(ip *c.Char, port c.Int, addr *net.SockaddrIn) c.Int From e40e2d2d14a5239fe3400394717d2dfc8b2b4d19 Mon Sep 17 00:00:00 2001 From: hackerchai Date: Tue, 6 Aug 2024 16:51:52 +0800 Subject: [PATCH 6/9] style(c/libuv): Use go type funcs & update demo(syanc_fs, echo_server) --- c/libuv/_demo/async_fs/async_fs.go | 40 ++++----- c/libuv/_demo/echo_server/echo_server.go | 12 +-- c/libuv/fs.go | 101 ++++++++++++++-------- c/libuv/libuv.go | 103 +++++++++++++++-------- c/libuv/signal.go | 18 ++-- 5 files changed, 175 insertions(+), 99 deletions(-) diff --git a/c/libuv/_demo/async_fs/async_fs.go b/c/libuv/_demo/async_fs/async_fs.go index 14b50ecd..36acff75 100644 --- a/c/libuv/_demo/async_fs/async_fs.go +++ b/c/libuv/_demo/async_fs/async_fs.go @@ -31,7 +31,7 @@ func main() { libuv.FsOpen(loop, &openReq, c.Str("example.txt"), os.O_RDONLY, 0, onOpen) // Run the loop - result := libuv.Run(loop, libuv.RUN_DEFAULT) + result := loop.Run(libuv.RUN_DEFAULT) if result != 0 { c.Fprintf(c.Stderr, c.Str("Error in Run: %s\n"), libuv.Strerror(libuv.Errno(result))) @@ -43,14 +43,14 @@ func main() { func onOpen(req *libuv.Fs) { // Check for errors - if libuv.FsGetResult(req) < 0 { - c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req)))) - libuv.LoopClose(loop) + if req.GetResult() < 0 { + c.Fprintf(c.Stderr, c.Str("Error opening file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult()))) + loop.Close() return } // Store the file descriptor - file = libuv.File(libuv.FsGetResult(req)) + file = libuv.File(req.GetResult()) // Init buffer iov = libuv.InitBuf((*c.Char)(unsafe.Pointer(&buffer[0])), c.Uint(unsafe.Sizeof(buffer))) @@ -68,28 +68,28 @@ func readFile() { readRes := libuv.FsRead(loop, &readReq, file, &iov, 1, -1, onRead) if readRes != 0 { c.Printf(c.Str("Error in FsRead: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(readRes)), readRes) - libuv.FsReqCleanup(&readReq) - libuv.LoopClose(loop) + readReq.ReqCleanup() + loop.Close() } } func onRead(req *libuv.Fs) { // Cleanup the request - defer libuv.FsReqCleanup(req) + defer req.ReqCleanup() // Check for errors - if libuv.FsGetResult(req) < 0 { - c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req)))) - } else if libuv.FsGetResult(req) == 0 { + if req.GetResult() < 0 { + c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult()))) + } else if req.GetResult() == 0 { // Close the file - closeRes := libuv.FsClose(loop, &closeReq, libuv.File(libuv.FsGetResult(&openReq)), onClose) + closeRes := libuv.FsClose(loop, &closeReq, libuv.File(openReq.GetResult()), onClose) if closeRes != 0 { c.Printf(c.Str("Error in FsClose: %s (code: %d)\n"), libuv.Strerror(libuv.Errno(closeRes)), closeRes) - libuv.LoopClose(loop) + loop.Close() return } } else { - c.Printf(c.Str("Read %d bytes\n"), libuv.FsGetResult(req)) - c.Printf(c.Str("Read content: %.*s\n"), libuv.FsGetResult(req), (*c.Char)(unsafe.Pointer(&buffer[0]))) + c.Printf(c.Str("Read %d bytes\n"), req.GetResult()) + c.Printf(c.Str("Read content: %.*s\n"), req.GetResult(), (*c.Char)(unsafe.Pointer(&buffer[0]))) // Read the file again readFile() } @@ -97,8 +97,8 @@ func onRead(req *libuv.Fs) { func onClose(req *libuv.Fs) { // Check for errors - if libuv.FsGetResult(req) < 0 { - c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(libuv.FsGetResult(req)))) + if req.GetResult() < 0 { + c.Fprintf(c.Stderr, c.Str("Error closing file: %s\n"), libuv.Strerror(libuv.Errno(req.GetResult()))) } else { c.Printf(c.Str("\nFile closed successfully.\n")) } @@ -106,10 +106,10 @@ func onClose(req *libuv.Fs) { func cleanup() { // Cleanup the requests - libuv.FsReqCleanup(&openReq) - libuv.FsReqCleanup(&closeReq) + openReq.ReqCleanup() + closeReq.ReqCleanup() // Close the loop - result := libuv.LoopClose(loop) + result := loop.Close() if result != 0 { c.Fprintf(c.Stderr, c.Str("Error in LoopClose: %s\n"), libuv.Strerror(libuv.Errno(result))) } diff --git a/c/libuv/_demo/echo_server/echo_server.go b/c/libuv/_demo/echo_server/echo_server.go index 2c9a71b8..f5b0b880 100644 --- a/c/libuv/_demo/echo_server/echo_server.go +++ b/c/libuv/_demo/echo_server/echo_server.go @@ -33,12 +33,12 @@ func main() { (&server).Bind((*net.SockAddr)(c.Pointer(&addr)), 0) res := (*libuv.Stream)(unsafe.Pointer(&server)).Listen(DEFAULT_BACKLOG, OnNewConnection) if res != 0 { - c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror((libuv.Errno(res)))) + c.Fprintf(c.Stderr, c.Str("Listen error: %s\n"), libuv.Strerror(libuv.Errno(res))) return } // Start listening for incoming connections - libuv.Run(loop, libuv.RUN_DEFAULT) + loop.Run(libuv.RUN_DEFAULT) } func FreeWriteReq(req *libuv.Write) { @@ -56,7 +56,7 @@ func AllocBuffer(handle *libuv.Handle, suggestedSize uintptr, buf *libuv.Buf) { func EchoWrite(req *libuv.Write, status c.Int) { if status != 0 { - c.Fprintf(c.Stderr, c.Str("Write error: %s\n"), libuv.Strerror((libuv.Errno(status)))) + c.Fprintf(c.Stderr, c.Str("Write error: %s\n"), libuv.Strerror(libuv.Errno(status))) } FreeWriteReq(req) } @@ -77,8 +77,8 @@ func EchoRead(client *libuv.Stream, nread c.Long, buf *libuv.Buf) { } if nread < 0 { // Handle read errors and EOF. - if (libuv.Errno)(nread) != libuv.EOF { - c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror((libuv.Errno)(nread))) + if libuv.Errno(nread) != libuv.EOF { + c.Fprintf(c.Stderr, c.Str("Read error: %s\n"), libuv.Strerror(libuv.Errno(nread))) } (*libuv.Handle)(c.Pointer(client)).Close(nil) } @@ -113,6 +113,6 @@ func OnNewConnection(server *libuv.Stream, status c.Int) { if server.Accept((*libuv.Stream)(unsafe.Pointer(client))) == 0 { (*libuv.Stream)(unsafe.Pointer(client)).StartRead(AllocBuffer, EchoRead) } else { - (*libuv.Handle)(c.Pointer(client)).Close(nil) + (*libuv.Handle)(unsafe.Pointer(client)).Close(nil) } } diff --git a/c/libuv/fs.go b/c/libuv/fs.go index 35152ffd..7c67fd73 100644 --- a/c/libuv/fs.go +++ b/c/libuv/fs.go @@ -108,29 +108,40 @@ type FsPollCb func(handle *FsPoll, status c.Int, events c.Int) /* Fs related function and method */ -//go:linkname FsGetType C.uv_fs_get_type -func FsGetType(req *Fs) FsType +// llgo:link (*Fs).GetType C.uv_fs_get_type +func (req *Fs) GetType() FsType { + return 0 +} -//go:linkname FsGetPath C.uv_fs_get_path -func FsGetPath(req *Fs) *c.Char +// llgo:link (*Fs).GetPath C.uv_fs_get_path +func (req *Fs) GetPath() *c.Char { + return nil +} -//go:linkname FsGetResult C.uv_fs_get_result -func FsGetResult(req *Fs) c.Int +// llgo:link (*Fs).GetResult C.uv_fs_get_result +func (req *Fs) GetResult() c.Int { + return 0 +} -//go:linkname FsGetPtr C.uv_fs_get_ptr -func FsGetPtr(req *Fs) c.Pointer +// llgo:link (*Fs).GetPtr C.uv_fs_get_ptr +func (req *Fs) GetPtr() c.Pointer { + return nil +} -//go:linkname FsGetSystemError C.uv_fs_get_system_error -func FsGetSystemError(req *Fs) c.Int +// llgo:link (*Fs).GetSystemError C.uv_fs_get_system_error +func (req *Fs) GetSystemError() c.Int { + return 0 +} -//go:linkname FsGetStatBuf C.uv_fs_get_statbuf -func FsGetStatBuf(req *Fs) *Stat +// llgo:link (*Fs).GetStatBuf C.uv_fs_get_statbuf +func (req *Fs) GetStatBuf() *Stat { + return nil +} -//go:linkname FsReqCleanup C.uv_fs_req_cleanup -func FsReqCleanup(req *Fs) - -//go:linkname DefaultLoop C.uv_default_loop -func DefaultLoop() *Loop +// llgo:link (*Fs).ReqCleanup C.uv_fs_req_cleanup +func (req *Fs) ReqCleanup() { + // No return value needed for this method +} //go:linkname FsOpen C.uv_fs_open func FsOpen(loop *Loop, req *Fs, path *c.Char, flags c.Int, mode c.Int, cb FsCb) c.Int @@ -243,32 +254,56 @@ func FsLchown(loop *Loop, req *Fs, path *c.Char, uid c.Int, gid c.Int, cb FsCb) //go:linkname FsLstat C.uv_fs_lstat func FsLstat(loop *Loop, req *Fs, path *c.Char, cb FsCb) c.Int +// ---------------------------------------------- + +/* FsEvent related function and method */ + //go:linkname FsEventInit C.uv_fs_event_init func FsEventInit(loop *Loop, handle *FsEvent) c.Int -//go:linkname FsEventStart C.uv_fs_event_start -func FsEventStart(handle *FsEvent, cb FsEventCb, path *c.Char, flags c.Int) c.Int +// llgo:link (*FsEvent).Start C.uv_fs_event_start +func (handle *FsEvent) Start(cb FsEventCb, path *c.Char, flags c.Int) c.Int { + return 0 +} -//go:linkname FsEventStop C.uv_fs_event_stop -func FsEventStop(handle *FsEvent) c.Int +// llgo:link (*FsEvent).Stop C.uv_fs_event_stop +func (handle *FsEvent) Stop() c.Int { + return 0 +} -//go:linkname FsEventClose C.uv_fs_event_close -func FsEventClose(handle *FsEvent) c.Int +// llgo:link (*FsEvent).Close C.uv_fs_event_close +func (handle *FsEvent) Close() c.Int { + return 0 +} -//go:linkname FsEventGetpath C.uv_fs_event_getpath -func FsEventGetpath(handle *FsEvent) *c.Char +// llgo:link (*FsEvent).Getpath C.uv_fs_event_getpath +func (handle *FsEvent) Getpath() *c.Char { + return nil +} + +// ---------------------------------------------- + +/* FsPoll related function and method */ //go:linkname FsPollInit C.uv_fs_poll_init func FsPollInit(loop *Loop, handle *FsPoll) c.Int -//go:linkname FsPollStart C.uv_fs_poll_start -func FsPollStart(handle *FsPoll, cb FsPollCb, path *c.Char, interval uint) c.Int +// llgo:link (*FsPoll).Start C.uv_fs_poll_start +func (handle *FsPoll) Start(cb FsPollCb, path *c.Char, interval uint) c.Int { + return 0 +} -//go:linkname FsPollStop C.uv_fs_poll_stop -func FsPollStop(handle *FsPoll) c.Int +// llgo:link (*FsPoll).Stop C.uv_fs_poll_stop +func (handle *FsPoll) Stop() c.Int { + return 0 +} -//go:linkname FsPollClose C.uv_fs_poll_close -func FsPollClose(handle *FsPoll) c.Int +// llgo:link (*FsPoll).Close C.uv_fs_poll_close +func (handle *FsPoll) Close() c.Int { + return 0 +} -//go:linkname FsPollGetPath C.uv_fs_poll_getpath -func FsPollGetPath(handle *FsPoll) *c.Char +// llgo:link (*FsPoll).GetPath C.uv_fs_poll_getpath +func (handle *FsPoll) GetPath() *c.Char { + return nil +} diff --git a/c/libuv/libuv.go b/c/libuv/libuv.go index 6a5e826c..4dbaeddf 100644 --- a/c/libuv/libuv.go +++ b/c/libuv/libuv.go @@ -155,50 +155,81 @@ func ReplaceAllocator(mallocFunc MallocFunc, reallocFunc ReallocFunc, callocFunc /* Loop related functions and method. */ +//go:linkname DefaultLoop C.uv_default_loop +func DefaultLoop() *Loop + //go:linkname LoopSize C.uv_loop_size func LoopSize() uintptr -//go:linkname Run C.uv_run -func Run(loop *Loop, mode RunMode) c.Int +// llgo:link (*Loop).Run C.uv_run +func (loop *Loop) Run(mode RunMode) c.Int { + return 0 +} -//go:linkname LoopAlive C.uv_loop_alive -func LoopAlive(loop *Loop) c.Int +// llgo:link (*Loop).Alive C.uv_loop_alive +func (loop *Loop) Alive() c.Int { + return 0 +} -//go:linkname LoopClose C.uv_loop_close -func LoopClose(loop *Loop) c.Int +// llgo:link (*Loop).Close C.uv_loop_close +func (loop *Loop) Close() c.Int { + return 0 +} -//go:linkname LoopConfigure C.uv_loop_configure -func LoopConfigure(loop *Loop, option LoopOption, arg c.Int) c.Int +// llgo:link (*Loop).Configure C.uv_loop_configure +func (loop *Loop) Configure(option LoopOption, arg c.Int) c.Int { + return 0 +} -//go:linkname LoopDefault C.uv_default_loop -func LoopDefault() *Loop +// llgo:link LoopDefault C.uv_default_loop +func LoopDefault() *Loop { + return nil +} -//go:linkname LoopDelete C.uv_loop_delete -func LoopDelete(loop *Loop) c.Int +// llgo:link (*Loop).Delete C.uv_loop_delete +func (loop *Loop) Delete() c.Int { + return 0 +} -//go:linkname LoopFork C.uv_loop_fork -func LoopFork(loop *Loop) c.Int +// llgo:link (*Loop).Fork C.uv_loop_fork +func (loop *Loop) Fork() c.Int { + return 0 +} -//go:linkname LoopInit C.uv_loop_init -func LoopInit(loop *Loop) c.Int +// llgo:link (*Loop).Init C.uv_loop_init +func (loop *Loop) Init() c.Int { + return 0 +} -//go:linkname LoopNew C.uv_loop_new -func LoopNew() *Loop +// llgo:link LoopNew C.uv_loop_new +func LoopNew() *Loop { + return nil +} -//go:linkname Now C.uv_now -func Now(loop *Loop) c.UlongLong +// llgo:link (*Loop).Now C.uv_now +func (loop *Loop) Now() c.UlongLong { + return 0 +} -//go:linkname UpdateTime C.uv_update_time -func UpdateTime(loop *Loop) +// llgo:link (*Loop).UpdateTime C.uv_update_time +func (loop *Loop) UpdateTime() { + // No return value needed for this method +} -//go:linkname BackendFd C.uv_backend_fd -func BackendFd(loop *Loop) c.Int +// llgo:link (*Loop).BackendFd C.uv_backend_fd +func (loop *Loop) BackendFd() c.Int { + return 0 +} -//go:linkname BackendTimeout C.uv_backend_timeout -func BackendTimeout(loop *Loop) c.Int +// llgo:link (*Loop).BackendTimeout C.uv_backend_timeout +func (loop *Loop) BackendTimeout() c.Int { + return 0 +} -//go:linkname Walk C.uv_walk -func Walk(loop *Loop, walkCb WalkCb, arg c.Pointer) +// llgo:link (*Loop).Walk C.uv_walk +func (loop *Loop) Walk(walkCb WalkCb, arg c.Pointer) { + // No return value needed for this method +} // ---------------------------------------------- @@ -214,11 +245,15 @@ func InitBuf(base *c.Char, len c.Uint) Buf //go:linkname PollInit C.uv_poll_init func PollInit(loop *Loop, handle *Poll, fd OsFd) c.Int -//go:linkname PollStart C.uv_poll_start -func PollStart(handle *Poll, events c.Int, cb PollCb) c.Int - -//go:linkname PollStop C.uv_poll_stop -func PollStop(handle *Poll) c.Int - //go:linkname PollInitSocket C.uv_poll_init_socket func PollInitSocket(loop *Loop, handle *Poll, socket c.Int) c.Int + +// llgo:link (*Poll).Start C.uv_poll_start +func (handle *Poll) Start(events c.Int, cb PollCb) c.Int { + return 0 +} + +// llgo:link (*Poll).Stop C.uv_poll_stop +func (handle *Poll) Stop() c.Int { + return 0 +} diff --git a/c/libuv/signal.go b/c/libuv/signal.go index bf8735d1..f2aa9ea7 100644 --- a/c/libuv/signal.go +++ b/c/libuv/signal.go @@ -26,11 +26,17 @@ type SignalCb func(handle *Signal, sigNum c.Int) //go:linkname SignalInit C.uv_signal_init func SignalInit(loop *Loop, handle *Signal) c.Int -//go:linkname SignalStart C.uv_signal_start -func SignalStart(handle *Signal, cb SignalCb, signum c.Int) c.Int +// llgo:link (*Signal).Start C.uv_signal_start +func (handle *Signal) Start(cb SignalCb, signum c.Int) c.Int { + return 0 +} -//go:linkname SignalStartOneshot C.uv_signal_start_oneshot -func SignalStartOneshot(handle *Signal, cb SignalCb, signum c.Int) c.Int +// llgo:link (*Signal).StartOneshot C.uv_signal_start_oneshot +func (handle *Signal) StartOneshot(cb SignalCb, signum c.Int) c.Int { + return 0 +} -//go:linkname SignalStop C.uv_signal_stop -func SignalStop(handle *Signal) c.Int +// llgo:link (*Signal).Stop C.uv_signal_stop +func (handle *Signal) Stop() c.Int { + return 0 +} From dd93a977904a4e229cc73807f5977544a808e340 Mon Sep 17 00:00:00 2001 From: hackerchai Date: Wed, 7 Aug 2024 11:53:57 +0800 Subject: [PATCH 7/9] Revert "feat(c/libuv): Add GetIoWatcherFd func" This reverts commit 1ce16727b1195a65c8f2c9de07a864ed5e3902ef. Signed-off-by: hackerchai --- c/libuv/net.go | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/c/libuv/net.go b/c/libuv/net.go index 3ceb10f2..7dbfa403 100644 --- a/c/libuv/net.go +++ b/c/libuv/net.go @@ -1,9 +1,5 @@ package libuv -//#cgo pkg-config: libuv -//#include -import "C" - import ( _ "unsafe" @@ -69,14 +65,22 @@ type UdpFlags c.Int /* Handle types. */ -type Tcp C.uv_tcp_t +// TODO(spongehah): Handle +type Handle struct { + Data c.Pointer + Unused [88]byte +} -type Handle C.uv_handle_t +// TODO(spongehah): Stream +type Stream struct { + Data c.Pointer + Unused [256]byte +} -type Stream C.uv_stream_t - -type Shutdown struct { - Unused [0]byte +// TODO(spongehah): Tcp +type Tcp struct { + Data c.Pointer + Unused [256]byte } type Udp struct { @@ -93,9 +97,17 @@ type UdpSend struct { Unused [0]byte } -type Connect C.uv_connect_t +// TODO(spongehah): Write +type Write struct { + Data c.Pointer + Unused [184]byte +} -type Write C.uv_write_t +// TODO(spongehah): Connect +type Connect struct { + Data c.Pointer + Unused [88]byte +} type GetAddrInfo struct { Unused [0]byte @@ -132,7 +144,6 @@ type ConnectionCb func(server *Stream, status c.Int) // llgo:type C type ShutdownCb func(req *Shutdown, status c.Int) - // ---------------------------------------------- /* Handle related function and method */ @@ -362,11 +373,6 @@ func (tcp *Tcp) CloseReset(closeCb CloseCb) c.Int { return 0 } -func (tcp *Tcp) GetIoWatcherFd() c.Int { - tcp_s := (*C.uv_tcp_t)(c.Pointer(tcp)) - return c.Int(tcp_s.io_watcher.fd) -} - //go:linkname TcpConnect C.uv_tcp_connect func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int From 3cd62994c76986a2a6becb9024a4e96acc0d0449 Mon Sep 17 00:00:00 2001 From: hackerchai Date: Wed, 7 Aug 2024 12:03:28 +0800 Subject: [PATCH 8/9] Revert "refactor(c/libuv): Use cgo alias replace struct assertion in fs" This reverts commit 45ba5b8dc50a13223e05ad673f4e57d7277d3f24. # Conflicts: # c/libuv/net.go --- c/libuv/fs.go | 8 +++----- c/libuv/net.go | 5 +++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/c/libuv/fs.go b/c/libuv/fs.go index 7c67fd73..71a78e85 100644 --- a/c/libuv/fs.go +++ b/c/libuv/fs.go @@ -1,9 +1,5 @@ package libuv -//#cgo pkg-config: libuv -//#include -import "C" - import ( _ "unsafe" @@ -72,7 +68,9 @@ type File c.Int /* Handle types. */ -type Fs C.uv_fs_t +type Fs struct { + Unused [440]byte +} type FsEvent struct { Unused [0]byte diff --git a/c/libuv/net.go b/c/libuv/net.go index 7dbfa403..80e8f186 100644 --- a/c/libuv/net.go +++ b/c/libuv/net.go @@ -117,6 +117,10 @@ type GetNameInfo struct { Unused [0]byte } +type Shutdown struct { + Unused [0]byte +} + // ---------------------------------------------- /* Function type */ @@ -144,6 +148,7 @@ type ConnectionCb func(server *Stream, status c.Int) // llgo:type C type ShutdownCb func(req *Shutdown, status c.Int) + // ---------------------------------------------- /* Handle related function and method */ From 8848222728635ff95385c41c095cdfd2fddaceaf Mon Sep 17 00:00:00 2001 From: hackerchai Date: Wed, 7 Aug 2024 14:48:15 +0800 Subject: [PATCH 9/9] feat(c/libuv): Add GetIoWatcherFd func using LLGoFiles --- c/libuv/_wrap/libuv.c | 5 +++++ c/libuv/libuv.go | 1 + c/libuv/net.go | 5 +++++ 3 files changed, 11 insertions(+) create mode 100644 c/libuv/_wrap/libuv.c diff --git a/c/libuv/_wrap/libuv.c b/c/libuv/_wrap/libuv.c new file mode 100644 index 00000000..d3d51448 --- /dev/null +++ b/c/libuv/_wrap/libuv.c @@ -0,0 +1,5 @@ +#include + +int uv_tcp_get_io_watcher_fd (uv_tcp_t* handle) { + return handle->io_watcher.fd; +} \ No newline at end of file diff --git a/c/libuv/libuv.go b/c/libuv/libuv.go index 4dbaeddf..2bf343a8 100644 --- a/c/libuv/libuv.go +++ b/c/libuv/libuv.go @@ -9,6 +9,7 @@ import ( const ( LLGoPackage = "link: $(pkg-config --libs libuv); -luv" + LLGoFiles = "$(pkg-config --cflags libuv): _wrap/libuv.c" ) // ---------------------------------------------- diff --git a/c/libuv/net.go b/c/libuv/net.go index 80e8f186..a8de9458 100644 --- a/c/libuv/net.go +++ b/c/libuv/net.go @@ -378,6 +378,11 @@ func (tcp *Tcp) CloseReset(closeCb CloseCb) c.Int { return 0 } +// llgo:link (*Tcp).GetIoWatcherFd C.uv_tcp_get_io_watcher_fd +func (tcp *Tcp) GetIoWatcherFd() c.Int { + return 0 +} + //go:linkname TcpConnect C.uv_tcp_connect func TcpConnect(req *Connect, tcp *Tcp, addr *net.SockAddr, connectCb ConnectCb) c.Int