Mongodb C++11 API errno 干扰
Mongodb C++11 API errno interference
似乎有很多mongodb c++11 函数将系统errno 代码更改为11 (EWOULDBLOCK / EAGAIN)。这目前正在干扰我程序的其余部分。我有几个问题:
- mongodb 将 errno 更改为 11 的原因是什么?
- 有什么办法可以避免在每次调用各种 mongodb 函数后必须重置 errno 吗?
下面的例子显示了 errno 的变化是多么普遍。示例改编自:https://www.mongodb.com/blog/post/introducing-new-c-driver?jmp=docs&_ga=1.90709144.367237569.1438109079
#include <iostream>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
int main(int, char**) {
errno = 0;
int counter(0);
std::string str;
mongocxx::instance inst{};
mongocxx::client conn{};
bsoncxx::builder::stream::document document{};
auto collection = conn["testdb"]["testcollection"];
document << "hello" << "world";
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
collection.insert_one(document.view());
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
errno = 0;
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
collection.insert_one(document.view());
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
errno = 0;
auto cursor = collection.find({});
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
for (auto&& doc : cursor) {
if (errno) {
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
errno = 0;
}
str = bsoncxx::to_json(doc);
//std::cout << str << std::endl;
printf("counter: %i\n",counter++);
}
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
collection.drop();
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
}
结果如下:
errno 0 ... hellomongo.cpp:22
errno 11 ... hellomongo.cpp:24
errno 0 ... hellomongo.cpp:27
errno 11 ... hellomongo.cpp:29
errno 0 ... hellomongo.cpp:34
errno 11 ... hellomongo.cpp:37
counter: 0
counter: 1
errno 0 ... hellomongo.cpp:46
errno 11 ... hellomongo.cpp:48
一般来说,您应该预料到对几乎所有库的几乎任何调用都会导致 errno 发生变化。
在内部,C++11 驱动程序构建在 C 驱动程序之上,它调用 socket(7) 子系统,设置 errno。特别是,C 驱动程序库进行非阻塞套接字 IO 调用,这解释了您在 errno.
中观察到的 EWOULDBLOCK/EAGAIN 值
一般来说,errno 的良好做法要求您在调用要提取详细错误信息的函数后立即 捕获 errno 值。干预调用可能会重置它。
似乎有很多mongodb c++11 函数将系统errno 代码更改为11 (EWOULDBLOCK / EAGAIN)。这目前正在干扰我程序的其余部分。我有几个问题:
- mongodb 将 errno 更改为 11 的原因是什么?
- 有什么办法可以避免在每次调用各种 mongodb 函数后必须重置 errno 吗?
下面的例子显示了 errno 的变化是多么普遍。示例改编自:https://www.mongodb.com/blog/post/introducing-new-c-driver?jmp=docs&_ga=1.90709144.367237569.1438109079
#include <iostream>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
int main(int, char**) {
errno = 0;
int counter(0);
std::string str;
mongocxx::instance inst{};
mongocxx::client conn{};
bsoncxx::builder::stream::document document{};
auto collection = conn["testdb"]["testcollection"];
document << "hello" << "world";
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
collection.insert_one(document.view());
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
errno = 0;
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
collection.insert_one(document.view());
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
errno = 0;
auto cursor = collection.find({});
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
for (auto&& doc : cursor) {
if (errno) {
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
errno = 0;
}
str = bsoncxx::to_json(doc);
//std::cout << str << std::endl;
printf("counter: %i\n",counter++);
}
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
collection.drop();
printf("errno %i ... %s:%i\n", errno, __FILE__, __LINE__);
}
结果如下:
errno 0 ... hellomongo.cpp:22
errno 11 ... hellomongo.cpp:24
errno 0 ... hellomongo.cpp:27
errno 11 ... hellomongo.cpp:29
errno 0 ... hellomongo.cpp:34
errno 11 ... hellomongo.cpp:37
counter: 0
counter: 1
errno 0 ... hellomongo.cpp:46
errno 11 ... hellomongo.cpp:48
一般来说,您应该预料到对几乎所有库的几乎任何调用都会导致 errno 发生变化。
在内部,C++11 驱动程序构建在 C 驱动程序之上,它调用 socket(7) 子系统,设置 errno。特别是,C 驱动程序库进行非阻塞套接字 IO 调用,这解释了您在 errno.
中观察到的 EWOULDBLOCK/EAGAIN 值一般来说,errno 的良好做法要求您在调用要提取详细错误信息的函数后立即 捕获 errno 值。干预调用可能会重置它。