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

Server-side FFI bindings #3084

Open
wants to merge 65 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
ba5f6d9
Add server-side FFI layer
bossmc Oct 17, 2022
391ccf9
Re-generate FFI headers
bossmc Oct 17, 2022
9faf327
Add example FFI server
bossmc Oct 17, 2022
42c3f67
Fix deadlock in executor poll_next
bossmc Oct 17, 2022
dbb54fd
Standardize ownership of conn_data in sample server code
bossmc Oct 17, 2022
ee3a806
Accept multiple incoming connections in a single poll
bossmc Oct 17, 2022
c1066a6
Support external C/LDFLAGS in Makefile
bossmc Oct 17, 2022
f626faf
Make sure we drop serverconn
bossmc Oct 18, 2022
1e8dbc5
Shutdown cleanly (at least when there are no in-flight transactions)
bossmc Oct 18, 2022
ec89a9e
Better logging on new connections
bossmc Oct 18, 2022
51350ec
Allow re-using connection options
bossmc Oct 20, 2022
a9a3e10
Improve feature checking for FFI module
bossmc Oct 20, 2022
7029c62
Allow reading Copy data from pointers
bossmc Oct 20, 2022
15b1b3a
Fill out request/response methods
bossmc Oct 20, 2022
997dd79
Service callback creates response
bossmc Oct 20, 2022
be3c00e
Fill out server connection options
bossmc Oct 20, 2022
ed80b09
Simplify gen_header
bossmc Oct 20, 2022
ad6393c
Remove hyper_serverconn wrapper
bossmc Oct 20, 2022
282c9ae
Add documentation for ffi server types and functions
bossmc Oct 20, 2022
4000e68
Linting the C code
bossmc Oct 21, 2022
0b2d900
Split up HTTP/1 and HTTP/2 options into separate structs
bossmc Oct 21, 2022
56ae2b4
(Re-)add ability to serve a dual stack (H1/H2)
bossmc Oct 21, 2022
425f72f
Fix const-correctness in http2_serverconn
bossmc Oct 21, 2022
da8ffb7
Remove dead code from server.c
bossmc Oct 22, 2022
e3983b0
Make `ffi` feature depend on `full` for now
bossmc Oct 22, 2022
a64b71e
Rust format the server code
bossmc Oct 22, 2022
56105c3
Format example C code
bossmc Oct 22, 2022
65fe1d5
Genericize AutoConnection
bossmc Oct 26, 2022
83278e7
Rename body::Recv to body::Incoming
bossmc Oct 31, 2022
30565f2
Add support for setting and firing timers
bossmc Nov 2, 2022
c3101ea
Expose timer-related APIs in server FFI
bossmc Nov 2, 2022
7f14762
Demonstrate timer processing in example
bossmc Nov 2, 2022
42b2518
More efficient timer heap
bossmc Nov 3, 2022
7c3ba18
Allow timer cancellation
bossmc Nov 4, 2022
750e031
Reduce number of timer entries in timer heap
bossmc Nov 8, 2022
be0e612
Move timer management to its own module
bossmc Nov 8, 2022
2aff1f3
Catchup merge from origin/master
bossmc Nov 16, 2022
4f04433
Merge remote-tracking branch 'origin/master' into server-ffi
bossmc Dec 9, 2022
787dfe9
Better C Makefile practices
bossmc Dec 9, 2022
c480ea8
Document parameters for hyper_request_method
bossmc Dec 14, 2022
d3cb7f6
Merge remote-tracking branch 'origin/master' into server-ffi
bossmc Dec 14, 2022
3d2f3ce
Fix up test for new Sleep API
bossmc Dec 14, 2022
df7386e
Install cargo-expand in CI for gen_header
bossmc Dec 14, 2022
0d9b99b
Fix up CI test for FFI builds
bossmc Dec 14, 2022
1de0922
Fix header handling for requests
Dec 21, 2022
553240b
Merge branch 'fix-request-headers' into 'server-ffi'
bossmc Dec 21, 2022
1203c15
Merge remote-tracking branch 'upstream/master' into server-ffi
bossmc Feb 26, 2023
69e146b
Allow passing a drop callback for IO userdata
bossmc Feb 27, 2023
f78a324
...and a drop callback for service userdata
bossmc Feb 28, 2023
b414b40
Add common handling for userdata drop/borrow semantics everywhere
bossmc Mar 14, 2023
9116dbc
Make hyper_userdata_drop visible in rust as well as C code
bossmc Mar 17, 2023
6ee013e
Merge remote-tracking branch 'origin/master' into server-ffi
bossmc Mar 17, 2023
d2e2315
Synchronize epoll event masks with hyper IO intents
bossmc Apr 12, 2023
c73a994
Fix copy-paste error
bossmc Apr 13, 2023
f5c283c
Merge branch 'master' into server-ffi
hawkw Apr 17, 2023
9b4c651
Merge remote-tracking branch 'origin/master' into server-ffi
bossmc Oct 12, 2023
caafc3e
Appease the formatting gods
bossmc Oct 12, 2023
0abf7e6
Apparently the new cbindgen uses a different ordering
bossmc Oct 12, 2023
1ada63b
Fix up doctests and bench builds
bossmc Oct 12, 2023
293ca8c
Format server.c with clang-format
bossmc Oct 12, 2023
023c9b2
Merge remote-tracking branch 'upstream/master' into server-ffi
bossmc Jan 27, 2024
aee894f
Merge remote-tracking branch 'upstream/master' into server-ffi
bossmc Aug 14, 2024
f5fa9df
Reduce body size in server example
bossmc Oct 22, 2024
ca2aaf6
Build server example with optimizations
bossmc Oct 22, 2024
89b23fc
Merge remote-tracking branch 'upstream/master' into server-ffi
bossmc Oct 22, 2024
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
6 changes: 3 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,15 @@ jobs:
- name: Build FFI
env:
RUSTFLAGS: --cfg hyper_unstable_ffi
run: cargo rustc --features client,http1,http2,ffi --crate-type cdylib
run: cargo rustc --features ffi --crate-type cdylib --release

- name: Make Examples
run: cd capi/examples && make client
run: cd capi/examples && make

- name: Run FFI unit tests
env:
RUSTFLAGS: --cfg hyper_unstable_ffi
run: cargo test --features server,client,http1,http2,ffi --lib
run: cargo test --features ffi --lib

ffi-header:
name: Verify hyper.h is up to date
Expand Down
11 changes: 3 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ want = { version = "0.3", optional = true }
[dev-dependencies]
form_urlencoded = "1"
futures-channel = { version = "0.3", features = ["sink"] }
futures-util = { version = "0.3", default-features = false, features = ["alloc", "sink"] }
futures-util = { version = "0.3", default-features = false, features = ["sink"] }
http-body-util = "0.1"
pretty_env_logger = "0.5"
spmc = "0.3"
Expand All @@ -69,12 +69,7 @@ tokio-util = "0.7.10"
default = []

# Easily turn it all on
full = [
"client",
"http1",
"http2",
"server",
]
full = ["client", "http1", "http2", "server", "futures-util?/alloc"]

# HTTP versions
http1 = ["dep:futures-channel", "dep:futures-util", "dep:httparse", "dep:itoa"]
Expand All @@ -85,7 +80,7 @@ client = ["dep:want", "dep:pin-project-lite", "dep:smallvec"]
server = ["dep:httpdate", "dep:pin-project-lite", "dep:smallvec"]

# C-API support (currently unstable (no semver))
ffi = ["dep:libc", "dep:http-body-util", "futures-util?/alloc"]
ffi = ["dep:libc", "full", "dep:http-body-util", "futures-util?/alloc"]

# Utilize tracing (currently unstable)
tracing = ["dep:tracing"]
Expand Down
40 changes: 4 additions & 36 deletions benches/support/tokiort.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
#![allow(dead_code)]
//! Various runtimes for hyper
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
time::{Duration, Instant},
};

use hyper::rt::{Sleep, Timer};
use pin_project_lite::pin_project;

#[derive(Clone)]
/// An Executor that uses the tokio runtime.
Expand All @@ -25,25 +23,20 @@ where
}

/// A Timer that uses the tokio runtime.

#[derive(Clone, Debug)]
pub struct TokioTimer;

impl Timer for TokioTimer {
fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {
Box::pin(TokioSleep {
inner: tokio::time::sleep(duration),
})
Box::pin(tokio::time::sleep(duration))
}

fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>> {
Box::pin(TokioSleep {
inner: tokio::time::sleep_until(deadline.into()),
})
Box::pin(tokio::time::sleep_until(deadline.into()))
}

fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
if let Some(sleep) = sleep.as_mut().downcast_mut_pin::<TokioSleep>() {
if let Some(sleep) = sleep.as_mut().downcast_mut_pin::<tokio::time::Sleep>() {
sleep.reset(new_deadline.into())
}
}
Expand All @@ -56,32 +49,7 @@ impl TokioTimer {
}
}

// Use TokioSleep to get tokio::time::Sleep to implement Unpin.
// see https://docs.rs/tokio/latest/tokio/time/struct.Sleep.html
pin_project! {
pub(crate) struct TokioSleep {
#[pin]
pub(crate) inner: tokio::time::Sleep,
}
}

impl Future for TokioSleep {
type Output = ();

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.project().inner.poll(cx)
}
}

impl Sleep for TokioSleep {}

impl TokioSleep {
pub fn reset(self: Pin<&mut Self>, deadline: Instant) {
self.project().inner.as_mut().reset(deadline.into());
}
}

pin_project! {
pin_project_lite::pin_project! {
#[derive(Debug)]
pub struct TokioIo<T> {
#[pin]
Expand Down
2 changes: 1 addition & 1 deletion capi/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ header = """/*
*
* Full docs at: https://docs.rs/hyper/latest/hyper/ffi/index.html
*/"""
include_guard = "_HYPER_H"
pragma_once = true
no_includes = true
sys_includes = ["stdint.h", "stddef.h", "stdbool.h"]
cpp_compat = true
Expand Down
191 changes: 191 additions & 0 deletions capi/examples/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
---
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: None
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: BinPack
BasedOnStyle: ''
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 1000
PenaltyIndentedWhitespace: 0
PointerAlignment: Right
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...

4 changes: 4 additions & 0 deletions capi/examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*.o
/server
/client
/upload
28 changes: 13 additions & 15 deletions capi/examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,22 @@
# Build the example client
#

TARGET = client
TARGET2 = upload

OBJS = client.o
OBJS2 = upload.o

RPATH=$(PWD)/../../target/debug
CFLAGS = -I../include
LDFLAGS = -L$(RPATH) -Wl,-rpath,$(RPATH)
RPATH=$(PWD)/../../target/release
HYPER_CFLAGS += -I../include -ggdb3 -O2
HYPER_LDFLAGS += -L$(RPATH) -Wl,-rpath,$(RPATH)
LIBS = -lhyper

all: $(TARGET) $(TARGET2)
all: client upload server

$(TARGET): $(OBJS)
$(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS)
%.o : %.c ../include/hyper.h
${CC} -c -o $@ $< $(HYPER_CFLAGS) $(CFLAGS)

$(TARGET2): $(OBJS2)
$(CC) -o $(TARGET2) $(OBJS2) $(LDFLAGS) $(LIBS)
client: client.o
$(CC) -o $@ $< $(HYPER_LDFLAGS) $(LDFLAGS) $(LIBS)
upload: upload.o
$(CC) -o $@ $< $(HYPER_LDFLAGS) $(LDFLAGS) $(LIBS)
server: server.o
$(CC) -o $@ $< $(HYPER_LDFLAGS) $(LDFLAGS) $(LIBS)

clean:
rm -f $(OBJS) $(TARGET) $(OBJS2) $(TARGET2)
rm -f *.o client server upload
Loading
Loading