Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pgsys module #67

Merged
merged 3 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,28 @@ pub fn build(b: *std.Build) void {
docs.dependOn(&build_docs.step);
}

// Reusable modules
const pgzx = blk: {
const module = b.addModule("pgzx", .{
.root_source_file = b.path("./src/pgzx.zig"),
// pgzx_pgsys module: C bindings to Postgres
const pgzx_pgsys = blk: {
const module = b.addModule("pgzx_pgsys", .{
.root_source_file = b.path("./src/pgzx/c.zig"),
.target = target,
.optimize = optimize,
});

// Internal C headers
module.addIncludePath(b.path("./src/pgzx/c/include/"));

// Postgres Headers
module.addIncludePath(.{
.cwd_relative = pgbuild.getIncludeServerDir(),
});
module.addIncludePath(.{
.cwd_relative = pgbuild.getIncludeDir(),
});
module.addLibraryPath(.{
.cwd_relative = pgbuild.getLibDir(),
});

// libpq support
module.addCSourceFiles(.{
.files = &[_][]const u8{
Expand All @@ -39,17 +50,24 @@ pub fn build(b: *std.Build) void {
"-I", pgbuild.getIncludeServerDir(),
},
});
module.addIncludePath(.{
.cwd_relative = pgbuild.getIncludeDir(),
});
module.addLibraryPath(.{
.cwd_relative = pgbuild.getLibDir(),
});
module.linkSystemLibrary("pq", .{});

break :blk module;
};

// pgzx: main project module.
// This module re-exports pgzx_pgsys, other generated modules, and utility functions.
const pgzx = blk: {
const module = b.addModule("pgzx", .{
.root_source_file = b.path("./src/pgzx.zig"),
.target = target,
.optimize = optimize,
});
module.addImport("pgzx_pgsys", pgzx_pgsys);

break :blk module;
};

// Unit test extension
const test_ext = blk: {
const test_options = b.addOptions();
Expand All @@ -63,9 +81,12 @@ pub fn build(b: *std.Build) void {
.link_libc = true,
.link_allow_shlib_undefined = true,
});
tests.lib.root_module.addOptions("build_options", test_options);

tests.lib.root_module.addIncludePath(b.path("./src/pgzx/c/include/"));

tests.lib.root_module.addImport("pgzx_pgsys", pgzx_pgsys);
tests.lib.root_module.addImport("pgzx", pgzx);
tests.lib.root_module.addOptions("build_options", test_options);

break :blk tests;
};
Expand Down
2 changes: 1 addition & 1 deletion src/pgzx.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
const std = @import("std");

// Export common set of postgres headers.
pub const c = @import("pgzx/c.zig");
pub const c = @import("pgzx_pgsys");

// Utility functions for working with the PostgreSQL C API.
pub const bgworker = @import("pgzx/bgworker.zig");
Expand Down
27 changes: 14 additions & 13 deletions src/pgzx/bgworker.zig
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
const std = @import("std");

const pgzx = @import("../pgzx.zig");
const c = @import("c.zig");
const pg = pgzx.c;

const elog = @import("elog.zig");
const err = @import("err.zig");
const lwlock = @import("lwlock.zig");

pub const BackgroundWorker = c.BackgroundWorker;
pub const BackgroundWorker = pg.BackgroundWorker;

pub const WorkerOptions = struct {
flags: c_int,
worker_type: ?[]const u8 = null,
start_time: c.BgWorkerStartTime = c.BgWorkerStart_RecoveryFinished,
start_time: pg.BgWorkerStartTime = pg.BgWorkerStart_RecoveryFinished,
restart_time: c_int = 1,
main_arg: c.Datum = 0,
main_arg: pg.Datum = 0,
extra: ?[]const u8 = null,
notify_pid: c.pid_t = 0,
notify_pid: pg.pid_t = 0,
};

pub fn register(
Expand All @@ -25,15 +26,15 @@ pub fn register(
options: WorkerOptions,
) void {
var bw = initBackgroundWorker(name, library_name, function_name, options);
c.RegisterBackgroundWorker(&bw);
pg.RegisterBackgroundWorker(&bw);
}

pub fn registerDynamic(
comptime name: []const u8,
comptime library_name: []const u8,
comptime function_name: []const u8,
options: WorkerOptions,
) !*c.BackgroundWorkerHandle {
) !*pg.BackgroundWorkerHandle {
std.log.debug("init background worker: {s} {s} {s}", .{
name,
library_name,
Expand All @@ -47,8 +48,8 @@ pub fn registerDynamic(
library_name,
function_name,
});
var handle: ?*c.BackgroundWorkerHandle = null;
const ok = c.RegisterDynamicBackgroundWorker(&bw, &handle);
var handle: ?*pg.BackgroundWorkerHandle = null;
const ok = pg.RegisterDynamicBackgroundWorker(&bw, &handle);
if (!ok) {
return err.PGError.FailStartBackgroundWorker;
}
Expand All @@ -66,8 +67,8 @@ fn initBackgroundWorker(
comptime library_name: []const u8,
comptime function_name: []const u8,
options: WorkerOptions,
) c.BackgroundWorker {
var bw = std.mem.zeroInit(c.BackgroundWorker, .{
) pg.BackgroundWorker {
var bw = std.mem.zeroInit(pg.BackgroundWorker, .{
.bgw_flags = options.flags,
.bgw_start_time = options.start_time,
.bgw_restart_time = options.restart_time,
Expand Down Expand Up @@ -110,8 +111,8 @@ pub inline fn sigFlagHandler(sig: *pgzx.intr.Signal) fn (c_int) callconv(.C) voi
pub fn finalizeSignal(arg: c_int) void {
_ = arg;
const save_errno = std.c._errno().*;
if (c.MyProc != null) {
c.SetLatch(&c.MyProc.*.procLatch);
if (pg.MyProc != null) {
pg.SetLatch(&pg.MyProc.*.procLatch);
}
std.c._errno().* = save_errno;
}
68 changes: 34 additions & 34 deletions src/pgzx/collections/dlist.zig
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! Postgres intrusive double linked list support.

const std = @import("std");
const c = @import("../c.zig");
const pg = @import("pgzx_pgsys");

fn initNode() c.dlist_node {
fn initNode() pg.dlist_node {
return .{ .prev = null, .next = null };
}

Expand All @@ -14,15 +14,15 @@ pub fn DList(comptime T: type, comptime node_field: std.meta.FieldEnum(T)) type
pub const Iterator = DListIter(T, node_field);
pub const descr = DListDescr(T, node_field);

list: c.dlist_head,
list: pg.dlist_head,

pub inline fn init() Self {
return .{ .list = .{ .head = initNode() } };
}

inline fn ensureInit(self: *Self) void {
if (self.list.head.next == null) {
c.dlist_init(&self.list);
pg.dlist_init(&self.list);
}
}

Expand All @@ -42,7 +42,7 @@ pub fn DList(comptime T: type, comptime node_field: std.meta.FieldEnum(T)) type
// The elemenst in `other` must be of type T and the same member node
// must have been used to insert the elements into `other`.
//
pub inline fn appendFromDList(self: *Self, other: *c.dlist_head) void {
pub inline fn appendFromDList(self: *Self, other: *pg.dlist_head) void {
appendDList(&self.list, other);
}

Expand All @@ -54,7 +54,7 @@ pub fn DList(comptime T: type, comptime node_field: std.meta.FieldEnum(T)) type
//
// The `other` list must be compatible with the current list. The
// element type and the node members must match the type of Self.
pub inline fn appendToDList(self: *const Self, other: *c.dlist_head) void {
pub inline fn appendToDList(self: *const Self, other: *pg.dlist_head) void {
appendDList(other, &self.list);
}

Expand All @@ -69,7 +69,7 @@ pub fn DList(comptime T: type, comptime node_field: std.meta.FieldEnum(T)) type
}
}

pub inline fn rawList(self: *Self) *c.dlist_head {
pub inline fn rawList(self: *Self) *pg.dlist_head {
return &self.list;
}

Expand All @@ -81,105 +81,105 @@ pub fn DList(comptime T: type, comptime node_field: std.meta.FieldEnum(T)) type
}

pub inline fn isEmpty(self: *const Self) bool {
return c.dlist_is_empty(&self.list);
return pg.dlist_is_empty(&self.list);
}

pub inline fn headNode(self: *const Self) *T {
if (self.isEmpty()) {
@panic("headNode on empty list");
}
const node = c.dlist_head_node(@constCast(&self.list));
const node = pg.dlist_head_node(@constCast(&self.list));
return descr.nodeParentPtr(node.?);
}

pub inline fn tailNode(self: *const Self) *T {
if (self.isEmpty()) {
@panic("tailNode on empty list");
}
const node = c.dlist_tail_node(@constCast(&self.list));
const node = pg.dlist_tail_node(@constCast(&self.list));
return descr.nodeParentPtr(node.?);
}

pub inline fn pushHead(self: *Self, node: *T) void {
c.dlist_push_head(&self.list, descr.nodePtr(node));
pg.dlist_push_head(&self.list, descr.nodePtr(node));
}

pub inline fn pushTail(self: *Self, node: *T) void {
c.dlist_push_tail(&self.list, descr.nodePtr(node));
pg.dlist_push_tail(&self.list, descr.nodePtr(node));
}

pub inline fn popHead(self: *Self) *T {
if (self.isEmpty()) {
@panic("popHead on empty list");
}
return descr.nodeParentPtr(c.dlist_pop_head_node(&self.list));
return descr.nodeParentPtr(pg.dlist_pop_head_node(&self.list));
}

pub inline fn popTail(self: *Self) *T {
if (self.isEmpty()) {
@panic("popTail on empty list");
}
const tail = c.dlist_tail_node(&self.list);
c.dlist_delete(tail);
const tail = pg.dlist_tail_node(&self.list);
pg.dlist_delete(tail);
return descr.nodeParentPtr(tail.?);
}

pub inline fn moveHead(self: *Self, node: *T) void {
c.dlist_move_head(&self.list, descr.nodePtr(node));
pg.dlist_move_head(&self.list, descr.nodePtr(node));
}

pub inline fn moveTail(self: *Self, node: *T) void {
c.dlist_move_tail(&self.list, descr.nodePtr(node));
pg.dlist_move_tail(&self.list, descr.nodePtr(node));
}

pub inline fn nextNode(self: *const Self, node: *T) *T {
return descr.nodeParentPtr(c.dlist_next_node(&self.list, descr.nodePtr(node)));
return descr.nodeParentPtr(pg.dlist_next_node(&self.list, descr.nodePtr(node)));
}

pub inline fn prevNode(self: *const Self, node: *T) *T {
return descr.nodeParentPtr(c.dlist_prev_node(&self.list, descr.nodePtr(node)));
return descr.nodeParentPtr(pg.dlist_prev_node(&self.list, descr.nodePtr(node)));
}

pub inline fn iterator(self: *const Self) Iterator {
return Iterator.init(&self.list);
}

pub inline fn insertAfter(node: *T, new_node: *T) void {
c.dlist_insert_after(descr.nodePtr(node), descr.nodePtr(new_node));
pg.dlist_insert_after(descr.nodePtr(node), descr.nodePtr(new_node));
}

pub inline fn insertBefore(node: *T, new_node: *T) void {
c.dlist_insert_before(descr.nodePtr(node), descr.nodePtr(new_node));
pg.dlist_insert_before(descr.nodePtr(node), descr.nodePtr(new_node));
}

pub inline fn delete(node: *T) void {
c.dlist_delete(descr.nodePtr(node));
pg.dlist_delete(descr.nodePtr(node));
}

pub inline fn deleteThorougly(node: *T) void {
c.dlist_delete_thoroughly(descr.nodePtr(node));
pg.dlist_delete_thoroughly(descr.nodePtr(node));
}

pub inline fn isDetached(node: *T) bool {
return c.dlist_is_detached(descr.nodePtr(node));
return pg.dlist_is_detached(descr.nodePtr(node));
}
};
}

fn appendDList(to: *c.dlist_head, from: *c.dlist_head) void {
if (c.dlist_is_empty(from)) {
fn appendDList(to: *pg.dlist_head, from: *pg.dlist_head) void {
if (pg.dlist_is_empty(from)) {
return;
}
if (to.head.next == null) {
c.dlist_init(to);
pg.dlist_init(to);
}

to.*.head.prev.*.next = from.*.head.next;
from.*.head.next.*.prev = to.*.head.prev;
from.*.head.prev.*.next = &to.*.head;
to.*.head.prev = from.*.head.prev;

c.dlist_init(from);
pg.dlist_init(from);
}

fn DListIter(comptime T: type, comptime node_field: std.meta.FieldEnum(T)) type {
Expand All @@ -188,9 +188,9 @@ fn DListIter(comptime T: type, comptime node_field: std.meta.FieldEnum(T)) type

const descr = DListDescr(T, node_field);

iter: c.dlist_iter,
iter: pg.dlist_iter,

pub fn init(list: *const c.dlist_head) Self {
pub fn init(list: *const pg.dlist_head) Self {
const end = &list.head;
return .{
.iter = .{
Expand All @@ -216,15 +216,15 @@ pub fn DListDescr(comptime T: type, comptime node_field: std.meta.FieldEnum(T))
return struct {
const node = std.meta.fieldInfo(T, node_field).name;

pub inline fn nodePtr(v: *T) *c.dlist_node {
pub inline fn nodePtr(v: *T) *pg.dlist_node {
return &@field(v, node);
}

pub inline fn nodeParentPtr(n: *c.dlist_node) *T {
pub inline fn nodeParentPtr(n: *pg.dlist_node) *T {
return @fieldParentPtr(node, n);
}

pub inline fn optNodeParentPtr(n: ?*c.dlist_node) ?*T {
pub inline fn optNodeParentPtr(n: ?*pg.dlist_node) ?*T {
return if (n) |p| nodeParentPtr(p) else null;
}
};
Expand All @@ -235,7 +235,7 @@ pub const TestSuite_DList = struct {

const T = struct {
value: u32,
node: c.dlist_node = initNode(),
node: pg.dlist_node = initNode(),
};

pub fn testEmpty() !void {
Expand Down
Loading