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

Switch uses of __attribute__((__constructor__)) to dynamic initializers #66

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 15 additions & 13 deletions proxygen/lib/http/HTTPHeaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,21 @@ bitset<256>& HTTPHeaders::perHopHeaderCodes() {
return perHopHeaderCodes;
}

void
HTTPHeaders::initGlobals() {
auto& perHopHeaders = perHopHeaderCodes();
perHopHeaders[HTTP_HEADER_CONNECTION] = true;
perHopHeaders[HTTP_HEADER_KEEP_ALIVE] = true;
perHopHeaders[HTTP_HEADER_PROXY_AUTHENTICATE] = true;
perHopHeaders[HTTP_HEADER_PROXY_AUTHORIZATION] = true;
perHopHeaders[HTTP_HEADER_PROXY_CONNECTION] = true;
perHopHeaders[HTTP_HEADER_TE] = true;
perHopHeaders[HTTP_HEADER_TRAILER] = true;
perHopHeaders[HTTP_HEADER_TRANSFER_ENCODING] = true;
perHopHeaders[HTTP_HEADER_UPGRADE] = true;
}
static struct HTTPHeadersInitGlobals {
public:
HTTPHeadersInitGlobals() {
auto& perHopHeaders = HTTPHeaders::perHopHeaderCodes();
perHopHeaders[HTTP_HEADER_CONNECTION] = true;
perHopHeaders[HTTP_HEADER_KEEP_ALIVE] = true;
perHopHeaders[HTTP_HEADER_PROXY_AUTHENTICATE] = true;
perHopHeaders[HTTP_HEADER_PROXY_AUTHORIZATION] = true;
perHopHeaders[HTTP_HEADER_PROXY_CONNECTION] = true;
perHopHeaders[HTTP_HEADER_TE] = true;
perHopHeaders[HTTP_HEADER_TRAILER] = true;
perHopHeaders[HTTP_HEADER_TRANSFER_ENCODING] = true;
perHopHeaders[HTTP_HEADER_UPGRADE] = true;
}
} s_HTTPHeadersInitGlobals;

HTTPHeaders::HTTPHeaders() :
deletedCount_(0) {
Expand Down
2 changes: 0 additions & 2 deletions proxygen/lib/http/HTTPHeaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,6 @@ class HTTPHeaders {
*/
bool transferHeaderIfPresent(folly::StringPiece name, HTTPHeaders& dest);

static void initGlobals() __attribute__ ((__constructor__));

// deletes the strings in headerNames_ that we own
void disposeOfHeaderNames();
};
Expand Down
14 changes: 8 additions & 6 deletions proxygen/lib/http/HTTPMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ namespace {
typedef std::vector<std::string> StringVector;
DEFINE_UNION_STATIC_CONST_NO_INIT(StringVector, Vector, s_methodStrings);

__attribute__((__constructor__))
void initMethodStrings() {
new (const_cast<StringVector*>(&s_methodStrings.data)) StringVector {
HTTP_METHOD_GEN(HTTP_METHOD_STR)
};
}
static struct InitMethodStrings {
public:
InitMethodStrings() {
new (const_cast<StringVector*>(&s_methodStrings.data)) StringVector{
HTTP_METHOD_GEN(HTTP_METHOD_STR)
};
}
} s_InitMethodStrings;

}

Expand Down
28 changes: 15 additions & 13 deletions proxygen/lib/http/codec/HTTP1xCodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1065,19 +1065,21 @@ HTTP1xCodec::onMessageCompleteCB(http_parser* parser) {
}
}

void
HTTP1xCodec::initParserSettings() {
kParserSettings.on_message_begin = HTTP1xCodec::onMessageBeginCB;
kParserSettings.on_url = HTTP1xCodec::onUrlCB;
kParserSettings.on_header_field = HTTP1xCodec::onHeaderFieldCB;
kParserSettings.on_header_value = HTTP1xCodec::onHeaderValueCB;
kParserSettings.on_headers_complete = HTTP1xCodec::onHeadersCompleteCB;
kParserSettings.on_body = HTTP1xCodec::onBodyCB;
kParserSettings.on_message_complete = HTTP1xCodec::onMessageCompleteCB;
kParserSettings.on_reason = HTTP1xCodec::onReasonCB;
kParserSettings.on_chunk_header = HTTP1xCodec::onChunkHeaderCB;
kParserSettings.on_chunk_complete = HTTP1xCodec::onChunkCompleteCB;
}
static struct HTTP1xCodecInitParserSettings {
public:
HTTP1xCodecInitParserSettings() {
HTTP1xCodec::kParserSettings.on_message_begin = HTTP1xCodec::onMessageBeginCB;
HTTP1xCodec::kParserSettings.on_url = HTTP1xCodec::onUrlCB;
HTTP1xCodec::kParserSettings.on_header_field = HTTP1xCodec::onHeaderFieldCB;
HTTP1xCodec::kParserSettings.on_header_value = HTTP1xCodec::onHeaderValueCB;
HTTP1xCodec::kParserSettings.on_headers_complete = HTTP1xCodec::onHeadersCompleteCB;
HTTP1xCodec::kParserSettings.on_body = HTTP1xCodec::onBodyCB;
HTTP1xCodec::kParserSettings.on_message_complete = HTTP1xCodec::onMessageCompleteCB;
HTTP1xCodec::kParserSettings.on_reason = HTTP1xCodec::onReasonCB;
HTTP1xCodec::kParserSettings.on_chunk_header = HTTP1xCodec::onChunkHeaderCB;
HTTP1xCodec::kParserSettings.on_chunk_complete = HTTP1xCodec::onChunkCompleteCB;
}
} s_HTTP1xCodecInitParserSettings;

bool HTTP1xCodec::supportsNextProtocol(const std::string& npn) {
return npn.length() == 8 && (npn == "http/1.0" || npn == "http/1.1");
Expand Down
4 changes: 2 additions & 2 deletions proxygen/lib/http/codec/HTTP1xCodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class HTTP1xCodec : public HTTPCodec {
static bool supportsNextProtocol(const std::string& npn);

private:
friend struct HTTP1xCodecInitParserSettings;

/** Simple state model used to track the parsing of HTTP headers */
enum class HeaderParseState : uint8_t {
kParsingHeaderIdle,
Expand Down Expand Up @@ -188,8 +190,6 @@ class HTTP1xCodec : public HTTPCodec {
static int onChunkCompleteCB(http_parser* parser);
static int onMessageCompleteCB(http_parser* parser);

static void initParserSettings() __attribute__ ((__constructor__));

static http_parser_settings kParserSettings;
};

Expand Down
21 changes: 12 additions & 9 deletions proxygen/lib/http/codec/SPDYCodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,18 @@ class SPDYStreamFailed : public std::exception {

std::bitset<256> SPDYCodec::perHopHeaderCodes_;

void SPDYCodec::initPerHopHeaders() {
// SPDY per-hop headers
perHopHeaderCodes_[HTTP_HEADER_CONNECTION] = true;
perHopHeaderCodes_[HTTP_HEADER_HOST] = true;
perHopHeaderCodes_[HTTP_HEADER_KEEP_ALIVE] = true;
perHopHeaderCodes_[HTTP_HEADER_PROXY_CONNECTION] = true;
perHopHeaderCodes_[HTTP_HEADER_TRANSFER_ENCODING] = true;
perHopHeaderCodes_[HTTP_HEADER_UPGRADE] = true;
}
static struct SPDYCodecInitPerHopHeaders {
public:
SPDYCodecInitPerHopHeaders() {
// SPDY per-hop headers
SPDYCodec::perHopHeaderCodes_[HTTP_HEADER_CONNECTION] = true;
SPDYCodec::perHopHeaderCodes_[HTTP_HEADER_HOST] = true;
SPDYCodec::perHopHeaderCodes_[HTTP_HEADER_KEEP_ALIVE] = true;
SPDYCodec::perHopHeaderCodes_[HTTP_HEADER_PROXY_CONNECTION] = true;
SPDYCodec::perHopHeaderCodes_[HTTP_HEADER_TRANSFER_ENCODING] = true;
SPDYCodec::perHopHeaderCodes_[HTTP_HEADER_UPGRADE] = true;
}
} s_SPDYCodecInitPerHopHeaders;

const SPDYVersionSettings& SPDYCodec::getVersionSettings(SPDYVersion version) {
// XXX: We new and leak the static here intentionally so it doesn't get
Expand Down
3 changes: 1 addition & 2 deletions proxygen/lib/http/codec/SPDYCodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,14 @@ class SPDYCodec: public HTTPParallelCodec {
static boost::optional<SPDYVersion> getVersion(const std::string& protocol);

private:
friend struct SPDYCodecInitPerHopHeaders;

/**
* Determines whether header with a given code is on the SPDY per-hop
* header blacklist.
*/
static std::bitset<256> perHopHeaderCodes_;

static void initPerHopHeaders() __attribute__ ((__constructor__));

/**
* Generates a frame of type SYN_STREAM
*/
Expand Down
26 changes: 15 additions & 11 deletions proxygen/lib/http/codec/compress/Huffman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,18 +310,22 @@ const uint8_t s_respBitsTable05[kTableSize] = {
DEFINE_UNION_STATIC_CONST_NO_INIT(HuffTree, ReqHuffTree, s_reqHuffTree05);
DEFINE_UNION_STATIC_CONST_NO_INIT(HuffTree, RespHuffTree, s_respHuffTree05);

__attribute__((__constructor__))
void initReqHuffTree05() {
// constructing the tree in-place
new (const_cast<HuffTree*>(&s_reqHuffTree05.data))
HuffTree(s_reqCodesTable05, s_reqBitsTable05);
}
static struct InitReqHuffTree05 {
public:
InitReqHuffTree05() {
// constructing the tree in-place
new (const_cast<HuffTree*>(&s_reqHuffTree05.data))
HuffTree(s_reqCodesTable05, s_reqBitsTable05);
}
} s_InitReqHuffTree05;

__attribute__((__constructor__))
void initRespHuffTree05() {
new (const_cast<HuffTree*>(&s_respHuffTree05.data))
HuffTree(s_respCodesTable05, s_respBitsTable05);
}
static struct InitRespHuffTree05 {
public:
InitRespHuffTree05() {
new (const_cast<HuffTree*>(&s_respHuffTree05.data))
HuffTree(s_respCodesTable05, s_respBitsTable05);
}
} s_InitRespHuffTree05;

const HuffTree& reqHuffTree05() {
return s_reqHuffTree05.data;
Expand Down
14 changes: 8 additions & 6 deletions proxygen/lib/http/codec/compress/StaticHeaderTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,14 @@ const int kEntriesSize = sizeof(s_tableEntries) / (2 * sizeof(const char*));
*/
DEFINE_UNION_STATIC_CONST_NO_INIT(StaticHeaderTable, StaticTable, s_table);

__attribute__((__constructor__))
void initStaticTable() {
// use placement new to initialize the static table
new (const_cast<StaticHeaderTable*>(&s_table.data))
StaticHeaderTable(s_tableEntries, kEntriesSize);
}
static struct InitStaticTable {
public:
InitStaticTable() {
// use placement new to initialize the static table
new (const_cast<StaticHeaderTable*>(&s_table.data))
StaticHeaderTable(s_tableEntries, kEntriesSize);
}
} s_InitStaticTable;

StaticHeaderTable::StaticHeaderTable(
const char* entries[][2],
Expand Down
12 changes: 7 additions & 5 deletions proxygen/lib/http/codec/compress/experimental/hpack9/Huffman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@ const uint8_t s_bitsTable09[kTableSize] = {
*/
DEFINE_UNION_STATIC_CONST_NO_INIT(HuffTree, HuffTree09, s_huffTree09);

__attribute__((__constructor__))
void initHuffTree09() {
new (const_cast<HuffTree*>(&s_huffTree09.data))
HuffTree(s_codesTable09, s_bitsTable09);
}
static struct InitHuffTree09 {
public:
InitHuffTree09() {
new (const_cast<HuffTree*>(&s_huffTree09.data))
HuffTree(s_codesTable09, s_bitsTable09);
}
} s_InitHuffTree09;

const HuffTree& huffTree09() {
return s_huffTree09.data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,14 @@ const int kEntriesSize = sizeof(s_tableEntries) / (2 * sizeof(const char*));
*/
DEFINE_UNION_STATIC_CONST_NO_INIT(StaticHeaderTable, StaticTable, s_table);

__attribute__((__constructor__))
void initStaticTable() {
// use placement new to initialize the static table
new (const_cast<StaticHeaderTable*>(&s_table.data))
StaticHeaderTable(s_tableEntries, kEntriesSize);
}
static struct InitStaticTable {
public:
InitStaticTable() {
// use placement new to initialize the static table
new (const_cast<StaticHeaderTable*>(&s_table.data))
StaticHeaderTable(s_tableEntries, kEntriesSize);
}
} s_InitStaticTable;

const HeaderTable& getStaticTable() {
return s_table.data;
Expand Down
21 changes: 12 additions & 9 deletions proxygen/lib/http/codec/experimental/HTTP2Codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,18 @@ uint32_t HTTP2Codec::kHeaderSplitSize{http2::kMaxFramePayloadLengthMin};

std::bitset<256> HTTP2Codec::perHopHeaderCodes_;

void HTTP2Codec::initPerHopHeaders() {
// HTTP/1.x per-hop headers that have no meaning in HTTP/2
perHopHeaderCodes_[HTTP_HEADER_CONNECTION] = true;
perHopHeaderCodes_[HTTP_HEADER_HOST] = true;
perHopHeaderCodes_[HTTP_HEADER_KEEP_ALIVE] = true;
perHopHeaderCodes_[HTTP_HEADER_PROXY_CONNECTION] = true;
perHopHeaderCodes_[HTTP_HEADER_TRANSFER_ENCODING] = true;
perHopHeaderCodes_[HTTP_HEADER_UPGRADE] = true;
}
static struct HTTP2CodecInitPerHopHeaders {
public:
HTTP2CodecInitPerHopHeaders() {
// HTTP/1.x per-hop headers that have no meaning in HTTP/2
HTTP2Codec::perHopHeaderCodes_[HTTP_HEADER_CONNECTION] = true;
HTTP2Codec::perHopHeaderCodes_[HTTP_HEADER_HOST] = true;
HTTP2Codec::perHopHeaderCodes_[HTTP_HEADER_KEEP_ALIVE] = true;
HTTP2Codec::perHopHeaderCodes_[HTTP_HEADER_PROXY_CONNECTION] = true;
HTTP2Codec::perHopHeaderCodes_[HTTP_HEADER_TRANSFER_ENCODING] = true;
HTTP2Codec::perHopHeaderCodes_[HTTP_HEADER_UPGRADE] = true;
}
} s_HTTP2CodecInitPerHopHeaders;

HTTP2Codec::HTTP2Codec(TransportDirection direction)
: HTTPParallelCodec(direction),
Expand Down
4 changes: 2 additions & 2 deletions proxygen/lib/http/codec/experimental/HTTP2Codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class HTTP2Codec: public HTTPParallelCodec, HeaderCodec::StreamingCallback {
}

private:
friend struct HTTP2CodecInitPerHopHeaders;

class HeaderDecodeInfo {
public:
explicit HeaderDecodeInfo(HTTPRequestVerifier v)
Expand Down Expand Up @@ -132,8 +134,6 @@ class HTTP2Codec: public HTTPParallelCodec, HeaderCodec::StreamingCallback {
*/
static std::bitset<256> perHopHeaderCodes_;

static void initPerHopHeaders() __attribute__ ((__constructor__));

ErrorCode parseFrame(folly::io::Cursor& cursor);
ErrorCode parseAllData(folly::io::Cursor& cursor);
ErrorCode parseDataFrameData(
Expand Down
52 changes: 27 additions & 25 deletions proxygen/lib/http/session/HTTPTransactionEgressSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,39 +29,41 @@ DEFINE_UNION_STATIC_CONST_NO_INIT(TransitionTable, Table, s_transitions);
// Start -> HeadersSent +----> EOMQueued --> SendingDone
// | ^
// +------------> RegularBodySent -------+
__attribute__((__constructor__))
void initTableUnion() {
// Use const_cast for the placement new initialization since we want this to
// be const after construction.
new (const_cast<TransitionTable*>(&s_transitions.data)) TransitionTable {
{{State::Start, Event::sendHeaders}, State::HeadersSent},
static struct InitTableUnion {
public:
InitTableUnion() {
// Use const_cast for the placement new initialization since we want this to
// be const after construction.
new (const_cast<TransitionTable*>(&s_transitions.data)) TransitionTable{
{{State::Start, Event::sendHeaders}, State::HeadersSent},

// For HTTP sending 100 response, then a regular response
{{State::HeadersSent, Event::sendHeaders}, State::HeadersSent},
// For HTTP sending 100 response, then a regular response
{{State::HeadersSent, Event::sendHeaders}, State::HeadersSent},

{{State::HeadersSent, Event::sendBody}, State::RegularBodySent},
{{State::HeadersSent, Event::sendChunkHeader}, State::ChunkHeaderSent},
{{State::HeadersSent, Event::sendEOM}, State::EOMQueued},
{{State::HeadersSent, Event::sendBody}, State::RegularBodySent},
{{State::HeadersSent, Event::sendChunkHeader}, State::ChunkHeaderSent},
{{State::HeadersSent, Event::sendEOM}, State::EOMQueued},

{{State::RegularBodySent, Event::sendBody}, State::RegularBodySent},
{{State::RegularBodySent, Event::sendEOM}, State::EOMQueued},
{{State::RegularBodySent, Event::sendBody}, State::RegularBodySent},
{{State::RegularBodySent, Event::sendEOM}, State::EOMQueued},

{{State::ChunkHeaderSent, Event::sendBody}, State::ChunkBodySent},
{{State::ChunkHeaderSent, Event::sendBody}, State::ChunkBodySent},

{{State::ChunkBodySent, Event::sendBody}, State::ChunkBodySent},
{{State::ChunkBodySent, Event::sendChunkTerminator},
State::ChunkTerminatorSent},
{{State::ChunkBodySent, Event::sendBody}, State::ChunkBodySent},
{{State::ChunkBodySent, Event::sendChunkTerminator},
State::ChunkTerminatorSent},

{{State::ChunkTerminatorSent, Event::sendChunkHeader},
State::ChunkHeaderSent},
{{State::ChunkTerminatorSent, Event::sendTrailers}, State::TrailersSent},
{{State::ChunkTerminatorSent, Event::sendEOM}, State::EOMQueued},
{{State::ChunkTerminatorSent, Event::sendChunkHeader},
State::ChunkHeaderSent},
{{State::ChunkTerminatorSent, Event::sendTrailers}, State::TrailersSent},
{{State::ChunkTerminatorSent, Event::sendEOM}, State::EOMQueued},

{{State::TrailersSent, Event::sendEOM}, State::EOMQueued},
{{State::TrailersSent, Event::sendEOM}, State::EOMQueued},

{{State::EOMQueued, Event::eomFlushed}, State::SendingDone},
};
}
{{State::EOMQueued, Event::eomFlushed}, State::SendingDone},
};
}
} s_InitTableUnion;

} // namespace

Expand Down