mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-01 19:37:45 +08:00
format code style
This commit is contained in:
parent
33e27867fc
commit
ea531338d6
@ -1,73 +1,73 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void* thread_main(void* ctx)
|
||||
{
|
||||
time_t begin, now;
|
||||
const char* user = (const char* ) ctx;
|
||||
|
||||
if (user && *user) {
|
||||
struct passwd* pwd = getpwnam(user);
|
||||
if (pwd == NULL) {
|
||||
printf("getpwnam error=%s, user=$%s\r\n",
|
||||
strerror(errno), user);
|
||||
return NULL;
|
||||
}
|
||||
if (setgid(pwd->pw_gid) < 0) {
|
||||
printf("setgid error=%s\r\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (initgroups(user, pwd->pw_gid) < 0) {
|
||||
printf("initgroups error=%s\r\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (setuid(pwd->pw_uid) < 0) {
|
||||
printf("setuid error=%s\r\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
printf("thread-%lu setuid ok\r\n", pthread_self());
|
||||
}
|
||||
|
||||
printf("thread-%lu: sleep a while\r\n", pthread_self());
|
||||
time(&begin);
|
||||
|
||||
while ((now = time(NULL)) <= begin + 5) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
printf("thread-%lu: my uid=%ld, gid=%ld, will exit\r\n",
|
||||
(long) getuid(), (long) getgid(), pthread_self());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MAX 10
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char* user = "nobody";
|
||||
pthread_t threads[MAX], tid;
|
||||
int i;
|
||||
|
||||
if (argc >= 2) {
|
||||
user = argv[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX; i++) {
|
||||
pthread_create(&threads[i], NULL, thread_main, NULL);
|
||||
}
|
||||
sleep(1);
|
||||
pthread_create(&tid, NULL, thread_main, user);
|
||||
|
||||
for (i = 0; i < MAX; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
pthread_join(tid, NULL);
|
||||
return 0;
|
||||
}
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void* thread_main(void* ctx)
|
||||
{
|
||||
time_t begin, now;
|
||||
const char* user = (const char* ) ctx;
|
||||
|
||||
if (user && *user) {
|
||||
struct passwd* pwd = getpwnam(user);
|
||||
if (pwd == NULL) {
|
||||
printf("getpwnam error=%s, user=$%s\r\n",
|
||||
strerror(errno), user);
|
||||
return NULL;
|
||||
}
|
||||
if (setgid(pwd->pw_gid) < 0) {
|
||||
printf("setgid error=%s\r\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (initgroups(user, pwd->pw_gid) < 0) {
|
||||
printf("initgroups error=%s\r\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (setuid(pwd->pw_uid) < 0) {
|
||||
printf("setuid error=%s\r\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
printf("thread-%lu setuid ok\r\n", pthread_self());
|
||||
}
|
||||
|
||||
printf("thread-%lu: sleep a while\r\n", pthread_self());
|
||||
time(&begin);
|
||||
|
||||
while ((now = time(NULL)) <= begin + 5) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
printf("thread-%lu: my uid=%ld, gid=%ld, will exit\r\n",
|
||||
(long) getuid(), (long) getgid(), pthread_self());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MAX 10
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char* user = "nobody";
|
||||
pthread_t threads[MAX], tid;
|
||||
int i;
|
||||
|
||||
if (argc >= 2) {
|
||||
user = argv[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX; i++) {
|
||||
pthread_create(&threads[i], NULL, thread_main, NULL);
|
||||
}
|
||||
sleep(1);
|
||||
pthread_create(&tid, NULL, thread_main, user);
|
||||
|
||||
for (i = 0; i < MAX; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
pthread_join(tid, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by lib_acl_cpp_vc2010.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by lib_acl_cpp_vc2010.rc
|
||||
//
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,263 +1,263 @@
|
||||
#include "stdafx.h"
|
||||
#include "http_stream.h"
|
||||
#include "http_client.h"
|
||||
|
||||
http_client::http_client(acl::aio_handle& handle)
|
||||
: handle_(handle)
|
||||
, refered_(0)
|
||||
, conn_timeout_(5)
|
||||
, rw_timeout_(5)
|
||||
, debug_(false)
|
||||
, redirect_limit_(5)
|
||||
, redirect_count_(0)
|
||||
, url_("/")
|
||||
, keep_alive_(true)
|
||||
, compressed_(false)
|
||||
{
|
||||
}
|
||||
|
||||
http_client::~http_client(void)
|
||||
{
|
||||
}
|
||||
|
||||
http_client& http_client::set_addr(const char* addr)
|
||||
{
|
||||
addr_ = addr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_timeout(int conn_timeout, int rw_timeout)
|
||||
{
|
||||
conn_timeout_ = conn_timeout;
|
||||
rw_timeout_ = rw_timeout;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_debug(bool on)
|
||||
{
|
||||
debug_ = on;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_redirect_limit(int max)
|
||||
{
|
||||
redirect_limit_ = max;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_url(const char* url)
|
||||
{
|
||||
url_ = url;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_host(const char* host)
|
||||
{
|
||||
host_ = host;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_keep_alive(bool yes)
|
||||
{
|
||||
keep_alive_ = yes;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool http_client::open(void)
|
||||
{
|
||||
http_stream* conn = new http_stream(handle_, *this);
|
||||
|
||||
conn->unzip_body(true);
|
||||
|
||||
acl::http_header& hdr = conn->request_header();
|
||||
hdr.set_url(url_)
|
||||
.set_host(host_)
|
||||
.accept_gzip(true)
|
||||
.set_keep_alive(keep_alive_);
|
||||
|
||||
acl::string buf;
|
||||
hdr.build_request(buf);
|
||||
printf("---------------request header-----------------\r\n");
|
||||
printf("[%s]\r\n", buf.c_str());
|
||||
|
||||
if (!conn->open(addr_, conn_timeout_, rw_timeout_)) {
|
||||
delete conn;
|
||||
return false;
|
||||
}
|
||||
|
||||
++__aio_refer;
|
||||
|
||||
// 本对象的引用计数递增
|
||||
refered_++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool http_client::redirect(const char* url)
|
||||
{
|
||||
char domain[256];
|
||||
unsigned short port;
|
||||
if (!acl::http_utils::get_addr(url, domain, sizeof(domain), &port)) {
|
||||
printf("invalid url=%s\r\n", url);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("\r\nredirect to url=%s\r\n\r\n", url);
|
||||
|
||||
const char http_pref[] = "http://", https_pref[] = "https://";
|
||||
|
||||
if (!strncasecmp(url, http_pref, sizeof(http_pref) - 1)) {
|
||||
url += sizeof(http_pref) - 1;
|
||||
} else if (strncasecmp(url, https_pref, sizeof(https_pref) - 1)) {
|
||||
url += sizeof(https_pref) - 1;
|
||||
}
|
||||
|
||||
const char* slash = strchr(url, '/');
|
||||
if (slash == NULL) {
|
||||
url = "/";
|
||||
} else {
|
||||
url = slash;
|
||||
}
|
||||
|
||||
acl::string addr;
|
||||
addr.format("%s|%d", domain, port);
|
||||
|
||||
set_addr(addr);
|
||||
set_url(url);
|
||||
set_host(domain);
|
||||
|
||||
if (open()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http_client::start(void)
|
||||
{
|
||||
if (open()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
void http_client::on_destroy(http_stream* conn)
|
||||
{
|
||||
printf("http_stream will be deleted!\r\n");
|
||||
delete conn;
|
||||
__destroy++;
|
||||
|
||||
if (--__aio_refer == 0) {
|
||||
printf("%s: stop aio engine now!\r\n", __FUNCTION__);
|
||||
handle_.stop();
|
||||
}
|
||||
|
||||
if (--refered_ == 0) {
|
||||
printf("============== delete http_client =============\r\n");
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void http_client::on_connect(http_stream& conn)
|
||||
{
|
||||
printf("--------------- connect server ok ------------\r\n");
|
||||
acl::string addr;
|
||||
if (conn.get_ns_addr(addr)) {
|
||||
printf(">>>ns server: %s\r\n", addr.c_str());
|
||||
}
|
||||
__connect_ok++;
|
||||
}
|
||||
|
||||
void http_client::on_disconnect(http_stream&)
|
||||
{
|
||||
printf("disconnect from server\r\n");
|
||||
__disconnect++;
|
||||
}
|
||||
|
||||
void http_client::on_ns_failed(http_stream&)
|
||||
{
|
||||
printf("dns lookup failed\r\n");
|
||||
__ns_failed++;
|
||||
}
|
||||
|
||||
void http_client::on_connect_timeout(http_stream&)
|
||||
{
|
||||
printf("connect timeout\r\n");
|
||||
__connect_timeout++;
|
||||
}
|
||||
|
||||
void http_client::on_connect_failed(http_stream&)
|
||||
{
|
||||
printf("connect failed\r\n");
|
||||
__connect_failed++;
|
||||
}
|
||||
|
||||
bool http_client::on_read_timeout(http_stream&)
|
||||
{
|
||||
printf("read timeout\r\n");
|
||||
__read_timeout++;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http_client::on_http_res_hdr(http_stream&, const acl::http_header& header)
|
||||
{
|
||||
acl::string buf;
|
||||
header.build_response(buf);
|
||||
|
||||
compressed_ = header.is_transfer_gzip();
|
||||
__header_ok++;
|
||||
|
||||
int http_status = header.get_status();
|
||||
|
||||
if (debug_) {
|
||||
printf("-----------%s: response header(status=%d)----\r\n",
|
||||
__FUNCTION__, http_status);
|
||||
printf("[%s]\r\n", buf.c_str());
|
||||
}
|
||||
|
||||
if (http_status == 301 || http_status == 302) {
|
||||
const char* location = header.get_entry("Location");
|
||||
if (location == NULL || *location == 0) {
|
||||
printf("Location null\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (++redirect_count_ > redirect_limit_) {
|
||||
printf("\r\nTOO MANY redirect!(%d > %d)\r\n\r\n",
|
||||
redirect_count_, redirect_limit_);
|
||||
return false;
|
||||
}
|
||||
|
||||
redirect(location);
|
||||
// 返回 false 以使当前连接关闭
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool http_client::on_http_res_body(http_stream& conn, char* data, size_t dlen)
|
||||
{
|
||||
if (!debug_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ret = conn.is_unzip_body();
|
||||
printf(">>>read body: %ld, unzip_body: %s\r\n",
|
||||
(long) dlen, ret ? "yes" : "no");
|
||||
|
||||
(void) write(1, data, dlen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool http_client::on_http_res_finish(http_stream&, bool success)
|
||||
{
|
||||
printf("\r\n---------------response over----------------\r\n");
|
||||
printf("http finish: keep_alive=%s, success=%s\r\n",
|
||||
keep_alive_ ? "true" : "false", success ? "ok" : "failed");
|
||||
__success++;
|
||||
|
||||
return keep_alive_;
|
||||
}
|
||||
#include "stdafx.h"
|
||||
#include "http_stream.h"
|
||||
#include "http_client.h"
|
||||
|
||||
http_client::http_client(acl::aio_handle& handle)
|
||||
: handle_(handle)
|
||||
, refered_(0)
|
||||
, conn_timeout_(5)
|
||||
, rw_timeout_(5)
|
||||
, debug_(false)
|
||||
, redirect_limit_(5)
|
||||
, redirect_count_(0)
|
||||
, url_("/")
|
||||
, keep_alive_(true)
|
||||
, compressed_(false)
|
||||
{
|
||||
}
|
||||
|
||||
http_client::~http_client(void)
|
||||
{
|
||||
}
|
||||
|
||||
http_client& http_client::set_addr(const char* addr)
|
||||
{
|
||||
addr_ = addr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_timeout(int conn_timeout, int rw_timeout)
|
||||
{
|
||||
conn_timeout_ = conn_timeout;
|
||||
rw_timeout_ = rw_timeout;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_debug(bool on)
|
||||
{
|
||||
debug_ = on;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_redirect_limit(int max)
|
||||
{
|
||||
redirect_limit_ = max;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_url(const char* url)
|
||||
{
|
||||
url_ = url;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_host(const char* host)
|
||||
{
|
||||
host_ = host;
|
||||
return *this;
|
||||
}
|
||||
|
||||
http_client& http_client::set_keep_alive(bool yes)
|
||||
{
|
||||
keep_alive_ = yes;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool http_client::open(void)
|
||||
{
|
||||
http_stream* conn = new http_stream(handle_, *this);
|
||||
|
||||
conn->unzip_body(true);
|
||||
|
||||
acl::http_header& hdr = conn->request_header();
|
||||
hdr.set_url(url_)
|
||||
.set_host(host_)
|
||||
.accept_gzip(true)
|
||||
.set_keep_alive(keep_alive_);
|
||||
|
||||
acl::string buf;
|
||||
hdr.build_request(buf);
|
||||
printf("---------------request header-----------------\r\n");
|
||||
printf("[%s]\r\n", buf.c_str());
|
||||
|
||||
if (!conn->open(addr_, conn_timeout_, rw_timeout_)) {
|
||||
delete conn;
|
||||
return false;
|
||||
}
|
||||
|
||||
++__aio_refer;
|
||||
|
||||
// 本对象的引用计数递增
|
||||
refered_++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool http_client::redirect(const char* url)
|
||||
{
|
||||
char domain[256];
|
||||
unsigned short port;
|
||||
if (!acl::http_utils::get_addr(url, domain, sizeof(domain), &port)) {
|
||||
printf("invalid url=%s\r\n", url);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("\r\nredirect to url=%s\r\n\r\n", url);
|
||||
|
||||
const char http_pref[] = "http://", https_pref[] = "https://";
|
||||
|
||||
if (!strncasecmp(url, http_pref, sizeof(http_pref) - 1)) {
|
||||
url += sizeof(http_pref) - 1;
|
||||
} else if (strncasecmp(url, https_pref, sizeof(https_pref) - 1)) {
|
||||
url += sizeof(https_pref) - 1;
|
||||
}
|
||||
|
||||
const char* slash = strchr(url, '/');
|
||||
if (slash == NULL) {
|
||||
url = "/";
|
||||
} else {
|
||||
url = slash;
|
||||
}
|
||||
|
||||
acl::string addr;
|
||||
addr.format("%s|%d", domain, port);
|
||||
|
||||
set_addr(addr);
|
||||
set_url(url);
|
||||
set_host(domain);
|
||||
|
||||
if (open()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http_client::start(void)
|
||||
{
|
||||
if (open()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
void http_client::on_destroy(http_stream* conn)
|
||||
{
|
||||
printf("http_stream will be deleted!\r\n");
|
||||
delete conn;
|
||||
__destroy++;
|
||||
|
||||
if (--__aio_refer == 0) {
|
||||
printf("%s: stop aio engine now!\r\n", __FUNCTION__);
|
||||
handle_.stop();
|
||||
}
|
||||
|
||||
if (--refered_ == 0) {
|
||||
printf("============== delete http_client =============\r\n");
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void http_client::on_connect(http_stream& conn)
|
||||
{
|
||||
printf("--------------- connect server ok ------------\r\n");
|
||||
acl::string addr;
|
||||
if (conn.get_ns_addr(addr)) {
|
||||
printf(">>>ns server: %s\r\n", addr.c_str());
|
||||
}
|
||||
__connect_ok++;
|
||||
}
|
||||
|
||||
void http_client::on_disconnect(http_stream&)
|
||||
{
|
||||
printf("disconnect from server\r\n");
|
||||
__disconnect++;
|
||||
}
|
||||
|
||||
void http_client::on_ns_failed(http_stream&)
|
||||
{
|
||||
printf("dns lookup failed\r\n");
|
||||
__ns_failed++;
|
||||
}
|
||||
|
||||
void http_client::on_connect_timeout(http_stream&)
|
||||
{
|
||||
printf("connect timeout\r\n");
|
||||
__connect_timeout++;
|
||||
}
|
||||
|
||||
void http_client::on_connect_failed(http_stream&)
|
||||
{
|
||||
printf("connect failed\r\n");
|
||||
__connect_failed++;
|
||||
}
|
||||
|
||||
bool http_client::on_read_timeout(http_stream&)
|
||||
{
|
||||
printf("read timeout\r\n");
|
||||
__read_timeout++;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool http_client::on_http_res_hdr(http_stream&, const acl::http_header& header)
|
||||
{
|
||||
acl::string buf;
|
||||
header.build_response(buf);
|
||||
|
||||
compressed_ = header.is_transfer_gzip();
|
||||
__header_ok++;
|
||||
|
||||
int http_status = header.get_status();
|
||||
|
||||
if (debug_) {
|
||||
printf("-----------%s: response header(status=%d)----\r\n",
|
||||
__FUNCTION__, http_status);
|
||||
printf("[%s]\r\n", buf.c_str());
|
||||
}
|
||||
|
||||
if (http_status == 301 || http_status == 302) {
|
||||
const char* location = header.get_entry("Location");
|
||||
if (location == NULL || *location == 0) {
|
||||
printf("Location null\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (++redirect_count_ > redirect_limit_) {
|
||||
printf("\r\nTOO MANY redirect!(%d > %d)\r\n\r\n",
|
||||
redirect_count_, redirect_limit_);
|
||||
return false;
|
||||
}
|
||||
|
||||
redirect(location);
|
||||
// 返回 false 以使当前连接关闭
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool http_client::on_http_res_body(http_stream& conn, char* data, size_t dlen)
|
||||
{
|
||||
if (!debug_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ret = conn.is_unzip_body();
|
||||
printf(">>>read body: %ld, unzip_body: %s\r\n",
|
||||
(long) dlen, ret ? "yes" : "no");
|
||||
|
||||
(void) write(1, data, dlen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool http_client::on_http_res_finish(http_stream&, bool success)
|
||||
{
|
||||
printf("\r\n---------------response over----------------\r\n");
|
||||
printf("http finish: keep_alive=%s, success=%s\r\n",
|
||||
keep_alive_ ? "true" : "false", success ? "ok" : "failed");
|
||||
__success++;
|
||||
|
||||
return keep_alive_;
|
||||
}
|
||||
|
@ -1,55 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
class http_stream;
|
||||
|
||||
class http_client
|
||||
{
|
||||
public:
|
||||
http_client(acl::aio_handle& handle);
|
||||
|
||||
bool start(void);
|
||||
|
||||
public:
|
||||
http_client& set_redirect_limit(int max);
|
||||
http_client& set_addr(const char* addr);
|
||||
http_client& set_timeout(int conn_timeout, int rw_timeout);
|
||||
http_client& set_debug(bool on);
|
||||
http_client& set_url(const char* url);
|
||||
http_client& set_host(const char* host);
|
||||
http_client& set_keep_alive(bool yes);
|
||||
|
||||
public:
|
||||
void on_destroy(http_stream* conn);
|
||||
void on_connect(http_stream& conn);
|
||||
void on_disconnect(http_stream& conn);
|
||||
void on_ns_failed(http_stream& conn);
|
||||
void on_connect_timeout(http_stream& conn);
|
||||
void on_connect_failed(http_stream& conn);
|
||||
bool on_read_timeout(http_stream& conn);
|
||||
|
||||
bool on_http_res_hdr(http_stream& conn, const acl::http_header& header);
|
||||
bool on_http_res_body(http_stream& conn, char* data, size_t dlen);
|
||||
bool on_http_res_finish(http_stream& conn, bool success);
|
||||
|
||||
private:
|
||||
~http_client(void);
|
||||
|
||||
bool redirect(const char* url);
|
||||
bool open(void);
|
||||
|
||||
private:
|
||||
acl::aio_handle& handle_;
|
||||
int refered_;
|
||||
|
||||
acl::string addr_;
|
||||
int conn_timeout_;
|
||||
int rw_timeout_;
|
||||
bool debug_;
|
||||
|
||||
int redirect_limit_;
|
||||
int redirect_count_;
|
||||
acl::string url_;
|
||||
acl::string host_;
|
||||
bool keep_alive_;
|
||||
bool compressed_;
|
||||
};
|
||||
#pragma once
|
||||
|
||||
class http_stream;
|
||||
|
||||
class http_client
|
||||
{
|
||||
public:
|
||||
http_client(acl::aio_handle& handle);
|
||||
|
||||
bool start(void);
|
||||
|
||||
public:
|
||||
http_client& set_redirect_limit(int max);
|
||||
http_client& set_addr(const char* addr);
|
||||
http_client& set_timeout(int conn_timeout, int rw_timeout);
|
||||
http_client& set_debug(bool on);
|
||||
http_client& set_url(const char* url);
|
||||
http_client& set_host(const char* host);
|
||||
http_client& set_keep_alive(bool yes);
|
||||
|
||||
public:
|
||||
void on_destroy(http_stream* conn);
|
||||
void on_connect(http_stream& conn);
|
||||
void on_disconnect(http_stream& conn);
|
||||
void on_ns_failed(http_stream& conn);
|
||||
void on_connect_timeout(http_stream& conn);
|
||||
void on_connect_failed(http_stream& conn);
|
||||
bool on_read_timeout(http_stream& conn);
|
||||
|
||||
bool on_http_res_hdr(http_stream& conn, const acl::http_header& header);
|
||||
bool on_http_res_body(http_stream& conn, char* data, size_t dlen);
|
||||
bool on_http_res_finish(http_stream& conn, bool success);
|
||||
|
||||
private:
|
||||
~http_client(void);
|
||||
|
||||
bool redirect(const char* url);
|
||||
bool open(void);
|
||||
|
||||
private:
|
||||
acl::aio_handle& handle_;
|
||||
int refered_;
|
||||
|
||||
acl::string addr_;
|
||||
int conn_timeout_;
|
||||
int rw_timeout_;
|
||||
bool debug_;
|
||||
|
||||
int redirect_limit_;
|
||||
int redirect_count_;
|
||||
acl::string url_;
|
||||
acl::string host_;
|
||||
bool keep_alive_;
|
||||
bool compressed_;
|
||||
};
|
||||
|
@ -1,70 +1,70 @@
|
||||
#include "stdafx.h"
|
||||
#include "http_client.h"
|
||||
#include "http_stream.h"
|
||||
|
||||
http_stream::http_stream(acl::aio_handle& handle, http_client& client)
|
||||
: http_aclient(handle, NULL)
|
||||
, client_(client)
|
||||
{
|
||||
}
|
||||
|
||||
http_stream::~http_stream(void)
|
||||
{
|
||||
printf("delete http_stream!\r\n");
|
||||
}
|
||||
|
||||
void http_stream::destroy(void)
|
||||
{
|
||||
client_.on_destroy(this);
|
||||
}
|
||||
|
||||
bool http_stream::on_connect(void)
|
||||
{
|
||||
client_.on_connect(*this);
|
||||
printf(">>> begin send_request\r\n");
|
||||
|
||||
//this->ws_handshake();
|
||||
this->send_request(NULL, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void http_stream::on_disconnect(void)
|
||||
{
|
||||
client_.on_disconnect(*this);
|
||||
}
|
||||
|
||||
void http_stream::on_ns_failed(void)
|
||||
{
|
||||
client_.on_ns_failed(*this);
|
||||
}
|
||||
|
||||
void http_stream::on_connect_timeout(void)
|
||||
{
|
||||
client_.on_connect_timeout(*this);
|
||||
}
|
||||
|
||||
void http_stream::on_connect_failed(void)
|
||||
{
|
||||
client_.on_connect_failed(*this);
|
||||
}
|
||||
|
||||
bool http_stream::on_read_timeout(void)
|
||||
{
|
||||
return client_.on_read_timeout(*this);
|
||||
}
|
||||
|
||||
bool http_stream::on_http_res_hdr(const acl::http_header& header)
|
||||
{
|
||||
return client_.on_http_res_hdr(*this, header);
|
||||
}
|
||||
|
||||
bool http_stream::on_http_res_body(char* data, size_t dlen)
|
||||
{
|
||||
return client_.on_http_res_body(*this, data, dlen);
|
||||
}
|
||||
|
||||
bool http_stream::on_http_res_finish(bool success)
|
||||
{
|
||||
return client_.on_http_res_finish(*this, success);
|
||||
}
|
||||
#include "stdafx.h"
|
||||
#include "http_client.h"
|
||||
#include "http_stream.h"
|
||||
|
||||
http_stream::http_stream(acl::aio_handle& handle, http_client& client)
|
||||
: http_aclient(handle, NULL)
|
||||
, client_(client)
|
||||
{
|
||||
}
|
||||
|
||||
http_stream::~http_stream(void)
|
||||
{
|
||||
printf("delete http_stream!\r\n");
|
||||
}
|
||||
|
||||
void http_stream::destroy(void)
|
||||
{
|
||||
client_.on_destroy(this);
|
||||
}
|
||||
|
||||
bool http_stream::on_connect(void)
|
||||
{
|
||||
client_.on_connect(*this);
|
||||
printf(">>> begin send_request\r\n");
|
||||
|
||||
//this->ws_handshake();
|
||||
this->send_request(NULL, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void http_stream::on_disconnect(void)
|
||||
{
|
||||
client_.on_disconnect(*this);
|
||||
}
|
||||
|
||||
void http_stream::on_ns_failed(void)
|
||||
{
|
||||
client_.on_ns_failed(*this);
|
||||
}
|
||||
|
||||
void http_stream::on_connect_timeout(void)
|
||||
{
|
||||
client_.on_connect_timeout(*this);
|
||||
}
|
||||
|
||||
void http_stream::on_connect_failed(void)
|
||||
{
|
||||
client_.on_connect_failed(*this);
|
||||
}
|
||||
|
||||
bool http_stream::on_read_timeout(void)
|
||||
{
|
||||
return client_.on_read_timeout(*this);
|
||||
}
|
||||
|
||||
bool http_stream::on_http_res_hdr(const acl::http_header& header)
|
||||
{
|
||||
return client_.on_http_res_hdr(*this, header);
|
||||
}
|
||||
|
||||
bool http_stream::on_http_res_body(char* data, size_t dlen)
|
||||
{
|
||||
return client_.on_http_res_body(*this, data, dlen);
|
||||
}
|
||||
|
||||
bool http_stream::on_http_res_finish(bool success)
|
||||
{
|
||||
return client_.on_http_res_finish(*this, success);
|
||||
}
|
||||
|
@ -1,45 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
class http_client;
|
||||
|
||||
class http_stream : public acl::http_aclient
|
||||
{
|
||||
public:
|
||||
http_stream(acl::aio_handle& handle, http_client& client);
|
||||
~http_stream(void);
|
||||
|
||||
protected:
|
||||
// @override
|
||||
void destroy(void);
|
||||
|
||||
// @override
|
||||
bool on_connect(void);
|
||||
|
||||
// @override
|
||||
void on_disconnect(void);
|
||||
|
||||
// @override
|
||||
void on_ns_failed(void);
|
||||
|
||||
// @override
|
||||
void on_connect_timeout(void);
|
||||
|
||||
// @override
|
||||
void on_connect_failed(void);
|
||||
|
||||
// @override
|
||||
bool on_read_timeout(void);
|
||||
|
||||
protected:
|
||||
// @override
|
||||
bool on_http_res_hdr(const acl::http_header& header);
|
||||
|
||||
// @override
|
||||
bool on_http_res_body(char* data, size_t dlen);
|
||||
|
||||
// @override
|
||||
bool on_http_res_finish(bool success);
|
||||
|
||||
private:
|
||||
http_client& client_;
|
||||
};
|
||||
#pragma once
|
||||
|
||||
class http_client;
|
||||
|
||||
class http_stream : public acl::http_aclient
|
||||
{
|
||||
public:
|
||||
http_stream(acl::aio_handle& handle, http_client& client);
|
||||
~http_stream(void);
|
||||
|
||||
protected:
|
||||
// @override
|
||||
void destroy(void);
|
||||
|
||||
// @override
|
||||
bool on_connect(void);
|
||||
|
||||
// @override
|
||||
void on_disconnect(void);
|
||||
|
||||
// @override
|
||||
void on_ns_failed(void);
|
||||
|
||||
// @override
|
||||
void on_connect_timeout(void);
|
||||
|
||||
// @override
|
||||
void on_connect_failed(void);
|
||||
|
||||
// @override
|
||||
bool on_read_timeout(void);
|
||||
|
||||
protected:
|
||||
// @override
|
||||
bool on_http_res_hdr(const acl::http_header& header);
|
||||
|
||||
// @override
|
||||
bool on_http_res_body(char* data, size_t dlen);
|
||||
|
||||
// @override
|
||||
bool on_http_res_finish(bool success);
|
||||
|
||||
private:
|
||||
http_client& client_;
|
||||
};
|
||||
|
@ -1,164 +1,164 @@
|
||||
#include <getopt.h>
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include "rocksdb/db.h"
|
||||
#include "rocksdb/slice.h"
|
||||
#include "rocksdb/options.h"
|
||||
|
||||
using namespace rocksdb;
|
||||
|
||||
class db_thread : public acl::thread {
|
||||
public:
|
||||
db_thread(int id, DB* db, const char* action, int max)
|
||||
: id_(id), db_(db), action_(action), max_(max) {}
|
||||
~db_thread(void) {
|
||||
delete db_;
|
||||
}
|
||||
|
||||
private:
|
||||
// @override
|
||||
void* run(void) {
|
||||
if (action_ == "add") {
|
||||
add(max_);
|
||||
} else if (action_ == "get") {
|
||||
get(max_);
|
||||
} else if (action_ == "del") {
|
||||
del(max_);
|
||||
} else {
|
||||
printf("invalid action=%s\r\n", action_.c_str());
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void add(int max) {
|
||||
Status s;
|
||||
acl::string key, value;
|
||||
int i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%d", id_, i);
|
||||
value.format("value-%d", i);
|
||||
|
||||
#if 0
|
||||
WriteBatch batch;
|
||||
batch.Put(key.c_str(), value.c_str());
|
||||
if (i > 0 && i % 1000 == 0) {
|
||||
s = db->Write(WriteOptions(), &batch);
|
||||
}
|
||||
#else
|
||||
s = db_->Put(WriteOptions(), key.c_str(), value.c_str());
|
||||
#endif
|
||||
if (!s.ok()) {
|
||||
printf("Put failed: %s, key=%s, value=%s\r\n",
|
||||
s.getState(), key.c_str(), value.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("add over, n=%d\r\n", i);
|
||||
}
|
||||
|
||||
void get(int max) {
|
||||
Status s;
|
||||
acl::string key;
|
||||
std::string value;
|
||||
int i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%d", id_, i);
|
||||
s = db_->Get(ReadOptions(), key.c_str(), &value);
|
||||
if (!s.ok()) {
|
||||
printf("Get failed, key=%s, error=%s\r\n",
|
||||
key.c_str(), s.getState());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("get over, n=%d\r\n", i);
|
||||
}
|
||||
|
||||
void del(int max) {
|
||||
Status s;
|
||||
acl::string key;
|
||||
int i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%d", id_, i);
|
||||
s = db_->Delete(WriteOptions(), key.c_str());
|
||||
if (!s.ok()) {
|
||||
printf("Del failed, key=%s, error=%s\r\n",
|
||||
key.c_str(), s.getState());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("del over, n=%d\r\n", i);
|
||||
}
|
||||
|
||||
private:
|
||||
int id_;
|
||||
DB* db_;
|
||||
acl::string action_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
static void usage(const char* procname)
|
||||
{
|
||||
printf("usage: %s -h [help]\r\n"
|
||||
" -c threads_count\r\n"
|
||||
" -a action[default: get, add|get|del]\r\n"
|
||||
" -n max_loop\r\n"
|
||||
, procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const char* dbpath = "./db";
|
||||
int ch, max = 1000, nthread = 1;
|
||||
acl::string action("get");
|
||||
|
||||
while ((ch = getopt(argc, argv, "hn:a:c:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 'n':
|
||||
max = atoi(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
action = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
nthread = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<acl::thread*> threads;
|
||||
for (int i = 0; i < nthread; i++) {
|
||||
DB* db;
|
||||
Options options;
|
||||
options.IncreaseParallelism();
|
||||
// options.OptimizeLevelStyleCompaction();
|
||||
options.create_if_missing = true;
|
||||
|
||||
acl::string path;
|
||||
path << dbpath << i;
|
||||
Status s = DB::Open(options, path.c_str(), &db);
|
||||
if (!s.ok()) {
|
||||
printf("Open rockdb(%s) failed(%s)!\r\n",
|
||||
dbpath, s.getState());
|
||||
return 1;
|
||||
}
|
||||
|
||||
acl::thread* thr = new db_thread(i, db, action, max);
|
||||
threads.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = threads.begin();
|
||||
it != threads.end(); ++it) {
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include <getopt.h>
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include "rocksdb/db.h"
|
||||
#include "rocksdb/slice.h"
|
||||
#include "rocksdb/options.h"
|
||||
|
||||
using namespace rocksdb;
|
||||
|
||||
class db_thread : public acl::thread {
|
||||
public:
|
||||
db_thread(int id, DB* db, const char* action, int max)
|
||||
: id_(id), db_(db), action_(action), max_(max) {}
|
||||
~db_thread(void) {
|
||||
delete db_;
|
||||
}
|
||||
|
||||
private:
|
||||
// @override
|
||||
void* run(void) {
|
||||
if (action_ == "add") {
|
||||
add(max_);
|
||||
} else if (action_ == "get") {
|
||||
get(max_);
|
||||
} else if (action_ == "del") {
|
||||
del(max_);
|
||||
} else {
|
||||
printf("invalid action=%s\r\n", action_.c_str());
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void add(int max) {
|
||||
Status s;
|
||||
acl::string key, value;
|
||||
int i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%d", id_, i);
|
||||
value.format("value-%d", i);
|
||||
|
||||
#if 0
|
||||
WriteBatch batch;
|
||||
batch.Put(key.c_str(), value.c_str());
|
||||
if (i > 0 && i % 1000 == 0) {
|
||||
s = db->Write(WriteOptions(), &batch);
|
||||
}
|
||||
#else
|
||||
s = db_->Put(WriteOptions(), key.c_str(), value.c_str());
|
||||
#endif
|
||||
if (!s.ok()) {
|
||||
printf("Put failed: %s, key=%s, value=%s\r\n",
|
||||
s.getState(), key.c_str(), value.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("add over, n=%d\r\n", i);
|
||||
}
|
||||
|
||||
void get(int max) {
|
||||
Status s;
|
||||
acl::string key;
|
||||
std::string value;
|
||||
int i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%d", id_, i);
|
||||
s = db_->Get(ReadOptions(), key.c_str(), &value);
|
||||
if (!s.ok()) {
|
||||
printf("Get failed, key=%s, error=%s\r\n",
|
||||
key.c_str(), s.getState());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("get over, n=%d\r\n", i);
|
||||
}
|
||||
|
||||
void del(int max) {
|
||||
Status s;
|
||||
acl::string key;
|
||||
int i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%d", id_, i);
|
||||
s = db_->Delete(WriteOptions(), key.c_str());
|
||||
if (!s.ok()) {
|
||||
printf("Del failed, key=%s, error=%s\r\n",
|
||||
key.c_str(), s.getState());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("del over, n=%d\r\n", i);
|
||||
}
|
||||
|
||||
private:
|
||||
int id_;
|
||||
DB* db_;
|
||||
acl::string action_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
static void usage(const char* procname)
|
||||
{
|
||||
printf("usage: %s -h [help]\r\n"
|
||||
" -c threads_count\r\n"
|
||||
" -a action[default: get, add|get|del]\r\n"
|
||||
" -n max_loop\r\n"
|
||||
, procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const char* dbpath = "./db";
|
||||
int ch, max = 1000, nthread = 1;
|
||||
acl::string action("get");
|
||||
|
||||
while ((ch = getopt(argc, argv, "hn:a:c:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 'n':
|
||||
max = atoi(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
action = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
nthread = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<acl::thread*> threads;
|
||||
for (int i = 0; i < nthread; i++) {
|
||||
DB* db;
|
||||
Options options;
|
||||
options.IncreaseParallelism();
|
||||
// options.OptimizeLevelStyleCompaction();
|
||||
options.create_if_missing = true;
|
||||
|
||||
acl::string path;
|
||||
path << dbpath << i;
|
||||
Status s = DB::Open(options, path.c_str(), &db);
|
||||
if (!s.ok()) {
|
||||
printf("Open rockdb(%s) failed(%s)!\r\n",
|
||||
dbpath, s.getState());
|
||||
return 1;
|
||||
}
|
||||
|
||||
acl::thread* thr = new db_thread(i, db, action, max);
|
||||
threads.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = threads.begin();
|
||||
it != threads.end(); ++it) {
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,213 +1,213 @@
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char* CREATE_TBL =
|
||||
"create table tbl_test\r\n"
|
||||
"(key varchar(128) not null,\r\n"
|
||||
" value varchar(128) not null,\r\n"
|
||||
" primary key(key))\r\n";
|
||||
|
||||
class dbthread : public acl::thread {
|
||||
public:
|
||||
dbthread(const char* dbpath, const char* action, int max, acl::atomic_long& count)
|
||||
: dbpath_(dbpath), action_(action), max_(max), count_(count) {}
|
||||
~dbthread(void) {}
|
||||
|
||||
private:
|
||||
acl::string dbpath_;
|
||||
acl::string action_;
|
||||
int max_;
|
||||
acl::atomic_long& count_;
|
||||
|
||||
void* run(void) {
|
||||
acl::db_sqlite db(dbpath_, "gbk");
|
||||
|
||||
if (db.open() == false) {
|
||||
printf("open %s error\r\n", dbpath_.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tbl_create(db, "tbl_test") == false) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ret;
|
||||
if (action_ == "add") {
|
||||
ret = dbadd(db, max_);
|
||||
} else if (action_ == "get") {
|
||||
ret = dbget(db, max_);
|
||||
} else if (action_ == "update") {
|
||||
ret = dbupdate(db, max_);
|
||||
} else if (action_ == "del") {
|
||||
ret = dbdel(db, max_);
|
||||
} else {
|
||||
printf("unknown action: %s\r\n", action_.c_str());
|
||||
return NULL;
|
||||
}
|
||||
printf("db-%s: %d\r\n", action_.c_str(), ret);
|
||||
if (ret > 0) {
|
||||
count_ += ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dbadd(acl::db_handle& db, int max) {
|
||||
acl::string sql;
|
||||
assert(db.begin_transaction());
|
||||
for (int i = 0; i < max; i++) {
|
||||
sql.format("insert into tbl_test('key', 'value')"
|
||||
" values('key-%d', 'value-%d')", i, i);
|
||||
if (db.sql_update(sql) == false) {
|
||||
printf("sql_update: |%s| error\r\n", sql.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i > 0 && i % 1000 == 0) {
|
||||
assert(db.commit());
|
||||
assert(db.begin_transaction());
|
||||
}
|
||||
}
|
||||
assert(db.commit());
|
||||
return max;
|
||||
}
|
||||
|
||||
int dbget(acl::db_handle& db, int max) {
|
||||
acl::string sql, key, value;
|
||||
int i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d", i);
|
||||
sql.format("select value from tbl_test"
|
||||
" where key='%s'", key.c_str());
|
||||
if (db.sql_select(sql) == false) {
|
||||
printf("sql_select: |%s| error\r\n", sql.c_str());
|
||||
return -1;
|
||||
}
|
||||
if (db.length() == 0) {
|
||||
break;
|
||||
}
|
||||
db.free_result();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int dbupdate(acl::db_handle& db, int max) {
|
||||
acl::string sql, key, value;
|
||||
for (int i = 0; i < max; i++) {
|
||||
key.format("key-%d", i);
|
||||
value.format("value-%d-%d", i, i);
|
||||
sql.format("update tbl_test set value = '%s'"
|
||||
" where key='%s'", value.c_str(), key.c_str());
|
||||
if (db.sql_update(sql) == false) {
|
||||
printf("sql_update: |%s| error\r\n", sql.c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
int dbdel(acl::db_handle& db, int max) {
|
||||
acl::string sql, key;
|
||||
int n = 0;
|
||||
for (int i = 0; i < max; i++) {
|
||||
key.format("key-%d", i);
|
||||
sql.format("delete from tbl_test where key='%s'",
|
||||
key.c_str());
|
||||
if (db.sql_update(sql) == false) {
|
||||
printf("sql_update: |%s| error\r\n", sql.c_str());
|
||||
return -1;
|
||||
}
|
||||
n += db.affect_count();
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
bool tbl_create(acl::db_handle& db, const char* tbl_name) {
|
||||
if (db.tbl_exists(tbl_name)) {
|
||||
return true;
|
||||
}
|
||||
if (db.sql_update(CREATE_TBL) == false) {
|
||||
printf("create table failed\r\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static void usage(const char* procname) {
|
||||
printf("usage: %s -h[help]\r\n"
|
||||
" -s listen_addr[default: 127.0.0.1:7343\r\n"
|
||||
" -n max[default: 1000]\r\n"
|
||||
" -c nthreads[default: 1]\r\n"
|
||||
" -p dbpath[default: .]\r\n"
|
||||
" -l libpath[default: libsqlite3.so]\r\n"
|
||||
" -a action[default: get, update|add|get|del\r\n"
|
||||
, procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int nthreads = 1, max = 1000, ch;
|
||||
acl::string dbpath = "./var", libpath = "./libsqlite3.so";
|
||||
acl::string action = "get";
|
||||
acl::string addr = "127.0.0.1:7343";
|
||||
|
||||
while ((ch = getopt(argc, argv, "hn:c:p:l:s:a:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 'n':
|
||||
max = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
nthreads = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
dbpath = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
libpath = optarg;
|
||||
break;
|
||||
case 's':
|
||||
addr = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
action = optarg;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (access(libpath.c_str(), R_OK) == -1) {
|
||||
printf("access %s failed %s\r\n", libpath.c_str(), acl::last_serror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
acl::log::stdout_open(true);
|
||||
acl::db_handle::set_loadpath(libpath);
|
||||
|
||||
acl::atomic_long success;
|
||||
|
||||
std::vector<acl::thread*> threads;
|
||||
for (int i = 0; i < nthreads; i++) {
|
||||
acl::string path;
|
||||
path << dbpath << "/" << "db" << i << ".db";
|
||||
acl::thread* thr = new dbthread(path, action, max, success);
|
||||
threads.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = threads.begin();
|
||||
it != threads.end(); ++it) {
|
||||
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
|
||||
printf("All over, nthreads=%d, total=%d, success=%lld\r\n",
|
||||
nthreads, nthreads * max, success.value());
|
||||
return 0;
|
||||
}
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char* CREATE_TBL =
|
||||
"create table tbl_test\r\n"
|
||||
"(key varchar(128) not null,\r\n"
|
||||
" value varchar(128) not null,\r\n"
|
||||
" primary key(key))\r\n";
|
||||
|
||||
class dbthread : public acl::thread {
|
||||
public:
|
||||
dbthread(const char* dbpath, const char* action, int max, acl::atomic_long& count)
|
||||
: dbpath_(dbpath), action_(action), max_(max), count_(count) {}
|
||||
~dbthread(void) {}
|
||||
|
||||
private:
|
||||
acl::string dbpath_;
|
||||
acl::string action_;
|
||||
int max_;
|
||||
acl::atomic_long& count_;
|
||||
|
||||
void* run(void) {
|
||||
acl::db_sqlite db(dbpath_, "gbk");
|
||||
|
||||
if (db.open() == false) {
|
||||
printf("open %s error\r\n", dbpath_.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tbl_create(db, "tbl_test") == false) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ret;
|
||||
if (action_ == "add") {
|
||||
ret = dbadd(db, max_);
|
||||
} else if (action_ == "get") {
|
||||
ret = dbget(db, max_);
|
||||
} else if (action_ == "update") {
|
||||
ret = dbupdate(db, max_);
|
||||
} else if (action_ == "del") {
|
||||
ret = dbdel(db, max_);
|
||||
} else {
|
||||
printf("unknown action: %s\r\n", action_.c_str());
|
||||
return NULL;
|
||||
}
|
||||
printf("db-%s: %d\r\n", action_.c_str(), ret);
|
||||
if (ret > 0) {
|
||||
count_ += ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dbadd(acl::db_handle& db, int max) {
|
||||
acl::string sql;
|
||||
assert(db.begin_transaction());
|
||||
for (int i = 0; i < max; i++) {
|
||||
sql.format("insert into tbl_test('key', 'value')"
|
||||
" values('key-%d', 'value-%d')", i, i);
|
||||
if (db.sql_update(sql) == false) {
|
||||
printf("sql_update: |%s| error\r\n", sql.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i > 0 && i % 1000 == 0) {
|
||||
assert(db.commit());
|
||||
assert(db.begin_transaction());
|
||||
}
|
||||
}
|
||||
assert(db.commit());
|
||||
return max;
|
||||
}
|
||||
|
||||
int dbget(acl::db_handle& db, int max) {
|
||||
acl::string sql, key, value;
|
||||
int i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d", i);
|
||||
sql.format("select value from tbl_test"
|
||||
" where key='%s'", key.c_str());
|
||||
if (db.sql_select(sql) == false) {
|
||||
printf("sql_select: |%s| error\r\n", sql.c_str());
|
||||
return -1;
|
||||
}
|
||||
if (db.length() == 0) {
|
||||
break;
|
||||
}
|
||||
db.free_result();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int dbupdate(acl::db_handle& db, int max) {
|
||||
acl::string sql, key, value;
|
||||
for (int i = 0; i < max; i++) {
|
||||
key.format("key-%d", i);
|
||||
value.format("value-%d-%d", i, i);
|
||||
sql.format("update tbl_test set value = '%s'"
|
||||
" where key='%s'", value.c_str(), key.c_str());
|
||||
if (db.sql_update(sql) == false) {
|
||||
printf("sql_update: |%s| error\r\n", sql.c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
int dbdel(acl::db_handle& db, int max) {
|
||||
acl::string sql, key;
|
||||
int n = 0;
|
||||
for (int i = 0; i < max; i++) {
|
||||
key.format("key-%d", i);
|
||||
sql.format("delete from tbl_test where key='%s'",
|
||||
key.c_str());
|
||||
if (db.sql_update(sql) == false) {
|
||||
printf("sql_update: |%s| error\r\n", sql.c_str());
|
||||
return -1;
|
||||
}
|
||||
n += db.affect_count();
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
bool tbl_create(acl::db_handle& db, const char* tbl_name) {
|
||||
if (db.tbl_exists(tbl_name)) {
|
||||
return true;
|
||||
}
|
||||
if (db.sql_update(CREATE_TBL) == false) {
|
||||
printf("create table failed\r\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static void usage(const char* procname) {
|
||||
printf("usage: %s -h[help]\r\n"
|
||||
" -s listen_addr[default: 127.0.0.1:7343\r\n"
|
||||
" -n max[default: 1000]\r\n"
|
||||
" -c nthreads[default: 1]\r\n"
|
||||
" -p dbpath[default: .]\r\n"
|
||||
" -l libpath[default: libsqlite3.so]\r\n"
|
||||
" -a action[default: get, update|add|get|del\r\n"
|
||||
, procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int nthreads = 1, max = 1000, ch;
|
||||
acl::string dbpath = "./var", libpath = "./libsqlite3.so";
|
||||
acl::string action = "get";
|
||||
acl::string addr = "127.0.0.1:7343";
|
||||
|
||||
while ((ch = getopt(argc, argv, "hn:c:p:l:s:a:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 'n':
|
||||
max = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
nthreads = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
dbpath = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
libpath = optarg;
|
||||
break;
|
||||
case 's':
|
||||
addr = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
action = optarg;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (access(libpath.c_str(), R_OK) == -1) {
|
||||
printf("access %s failed %s\r\n", libpath.c_str(), acl::last_serror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
acl::log::stdout_open(true);
|
||||
acl::db_handle::set_loadpath(libpath);
|
||||
|
||||
acl::atomic_long success;
|
||||
|
||||
std::vector<acl::thread*> threads;
|
||||
for (int i = 0; i < nthreads; i++) {
|
||||
acl::string path;
|
||||
path << dbpath << "/" << "db" << i << ".db";
|
||||
acl::thread* thr = new dbthread(path, action, max, success);
|
||||
threads.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = threads.begin();
|
||||
it != threads.end(); ++it) {
|
||||
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
|
||||
printf("All over, nthreads=%d, total=%d, success=%lld\r\n",
|
||||
nthreads, nthreads * max, success.value());
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,312 +1,312 @@
|
||||
#include <getopt.h>
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include <wiredtiger.h>
|
||||
|
||||
static acl::atomic_long __count = 0;
|
||||
static int __inter = 10000;
|
||||
|
||||
class wdb {
|
||||
public:
|
||||
wdb(const char* home)
|
||||
: home_(home)
|
||||
, conn_(NULL)
|
||||
{}
|
||||
|
||||
~wdb(void) {
|
||||
if (conn_) {
|
||||
conn_->close(conn_, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool open(void) {
|
||||
if (conn_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int ret = wiredtiger_open(home_.c_str(), NULL, "create", &conn_);
|
||||
if (ret != 0) {
|
||||
printf("open %s failed, ret=%d\r\n", home_.c_str(), ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WT_CONNECTION* get_conn(void) const {
|
||||
return conn_;
|
||||
}
|
||||
|
||||
private:
|
||||
acl::string home_;
|
||||
WT_CONNECTION *conn_;
|
||||
};
|
||||
|
||||
class wdb_sess {
|
||||
public:
|
||||
wdb_sess(wdb& db)
|
||||
: db_(db)
|
||||
, session_(NULL)
|
||||
, cursor_(NULL) {}
|
||||
|
||||
~wdb_sess(void) {}
|
||||
|
||||
bool open(void) {
|
||||
bool ret = db_.get_conn()->open_session(db_.get_conn(),
|
||||
NULL, NULL, &session_);
|
||||
if (ret != 0) {
|
||||
printf("open session failed, ret=%d\r\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = session_->create(session_, "table:access",
|
||||
"key_format=S, value_format=S");
|
||||
if (ret != 0) {
|
||||
printf("create session failed, ret=%d\r\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = session_->open_cursor(session_, "table:access",
|
||||
NULL, NULL, &cursor_);
|
||||
if (ret != 0) {
|
||||
printf("create table failed, ret=%d\r\n", ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool add(const char* key, const char* value) {
|
||||
assert(cursor_);
|
||||
cursor_->set_key(cursor_, key);
|
||||
cursor_->set_value(cursor_, value);
|
||||
int ret = cursor_->insert(cursor_);
|
||||
if (ret != 0) {
|
||||
printf("insert %s %s failed, ret=%d\r\n", key, value, ret);
|
||||
return false;
|
||||
}
|
||||
cursor_->reset(cursor_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get(const char* key, acl::string& value) {
|
||||
assert(cursor_);
|
||||
cursor_->set_key(cursor_, key);
|
||||
int ret = cursor_->search(cursor_);
|
||||
if (ret != 0) {
|
||||
printf("search %s failed, ret=%d\r\n", key, ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* v;
|
||||
ret = cursor_->get_value(cursor_, &v);
|
||||
if (ret != 0) {
|
||||
printf("get_value %s failed, ret=%d\r\n", key, ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
value = v;
|
||||
cursor_->reset(cursor_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool del(const char* key) {
|
||||
assert(cursor_);
|
||||
cursor_->set_key(cursor_, key);
|
||||
int ret = cursor_->remove(cursor_);
|
||||
if (ret != 0) {
|
||||
printf("remove %s failed, ret=%d\r\n", key, ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
cursor_->reset(cursor_);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
wdb& db_;
|
||||
WT_SESSION *session_;
|
||||
WT_CURSOR *cursor_;
|
||||
};
|
||||
|
||||
class db_thread : public acl::thread {
|
||||
public:
|
||||
db_thread(int id, wdb& db, const char* action, int max)
|
||||
: id_(id), db_(db), action_(action), max_(max) {}
|
||||
|
||||
~db_thread(void) {}
|
||||
|
||||
private:
|
||||
// @override
|
||||
void* run(void) {
|
||||
wdb_sess sess(db_);
|
||||
if (sess.open() == false) {
|
||||
printf("open db session failed\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (action_ == "add") {
|
||||
add(sess, max_);
|
||||
} else if (action_ == "get") {
|
||||
get(sess, max_);
|
||||
} else if (action_ == "del") {
|
||||
del(sess, max_);
|
||||
} else {
|
||||
printf("invalid action=%s\r\n", action_.c_str());
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void add(wdb_sess& sess, long long max) {
|
||||
acl::string key, value;
|
||||
long long i, n;
|
||||
|
||||
struct timeval begin;
|
||||
gettimeofday(&begin, NULL);
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%lld", id_, i);
|
||||
value.format("value-%lld", i);
|
||||
bool ret = sess.add(key.c_str(), value.c_str());
|
||||
if (!ret) {
|
||||
printf("add failed, key=%s, value=%s\r\n",
|
||||
key.c_str(), value.c_str());
|
||||
break;
|
||||
}
|
||||
n = ++__count;
|
||||
if (i % __inter == 0) {
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), "i=%lld, count=%lld, value=%s",
|
||||
i, n, value.c_str());
|
||||
acl::meter_time(__FILE__, __LINE__, buf);
|
||||
}
|
||||
}
|
||||
|
||||
struct timeval end;
|
||||
gettimeofday(&end, NULL);
|
||||
double spent = acl::stamp_sub(end, begin);
|
||||
double speed = (i * 1000) / ( spent > 1 ? spent : 1);
|
||||
printf("add over, n=%lld, spent=%.2f seconds, speed=%.2f\r\n",
|
||||
i, spent / 1000, speed);
|
||||
}
|
||||
|
||||
void get(wdb_sess& sess, long long max) {
|
||||
acl::string key, value;
|
||||
long long i;
|
||||
long long n, j = 0, k = max - 1;
|
||||
|
||||
struct timeval begin;
|
||||
gettimeofday(&begin, NULL);
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
if (i % 2 == 0) {
|
||||
key.format("key-%d-%lld", id_, j++);
|
||||
} else {
|
||||
key.format("key-%d-%lld", id_, k--);
|
||||
}
|
||||
|
||||
bool ret = sess.get(key.c_str(), value);
|
||||
if (!ret) {
|
||||
printf("Get failed, key=%s\r\n", key.c_str());
|
||||
break;
|
||||
} else if (i < 10) {
|
||||
printf("key=%s, value=%s\r\n",
|
||||
key.c_str(), value.c_str());
|
||||
}
|
||||
n = ++__count;
|
||||
if (i % __inter == 0) {
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), "i=%lld, count=%lld, value=%s",
|
||||
i, n, value.c_str());
|
||||
acl::meter_time(__FILE__, __LINE__, buf);
|
||||
}
|
||||
}
|
||||
|
||||
struct timeval end;
|
||||
gettimeofday(&end, NULL);
|
||||
double spent = acl::stamp_sub(end, begin);
|
||||
double speed = (i * 1000) / ( spent > 1 ? spent : 1);
|
||||
printf("get over, n=%lld, spend=%.2f seconds, speed=%.2f\r\n",
|
||||
i, spent / 1000, speed);
|
||||
}
|
||||
|
||||
void del(wdb_sess& sess, long long max) {
|
||||
acl::string key;
|
||||
long long i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%lld", id_, i);
|
||||
bool ret = sess.del(key.c_str());
|
||||
if (!ret) {
|
||||
printf("Del failed, key=%s\r\n", key.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("del over, n=%lld\r\n", i);
|
||||
}
|
||||
|
||||
private:
|
||||
int id_;
|
||||
wdb& db_;
|
||||
acl::string action_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
static void usage(const char* procname)
|
||||
{
|
||||
printf("usage: %s -h [help]\r\n"
|
||||
" -c threads_count\r\n"
|
||||
" -a action[default: get, add|get|del]\r\n"
|
||||
" -n max_loop\r\n"
|
||||
" -i inter\r\n"
|
||||
, procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const char* dbpath = "./db";
|
||||
int ch, max = 1000, nthread = 1;
|
||||
acl::string action("get");
|
||||
|
||||
while ((ch = getopt(argc, argv, "hn:a:c:i:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 'n':
|
||||
max = atoi(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
action = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
nthread = atoi(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
__inter = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
acl::string path;
|
||||
path << dbpath;
|
||||
wdb db(path);
|
||||
if (!db.open()) {
|
||||
printf("open db(%s) error\r\n", dbpath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<acl::thread*> threads;
|
||||
for (int i = 0; i < nthread; i++) {
|
||||
acl::thread* thr = new db_thread(i, db, action, max);
|
||||
threads.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = threads.begin();
|
||||
it != threads.end(); ++it) {
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include <getopt.h>
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include <wiredtiger.h>
|
||||
|
||||
static acl::atomic_long __count = 0;
|
||||
static int __inter = 10000;
|
||||
|
||||
class wdb {
|
||||
public:
|
||||
wdb(const char* home)
|
||||
: home_(home)
|
||||
, conn_(NULL)
|
||||
{}
|
||||
|
||||
~wdb(void) {
|
||||
if (conn_) {
|
||||
conn_->close(conn_, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool open(void) {
|
||||
if (conn_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int ret = wiredtiger_open(home_.c_str(), NULL, "create", &conn_);
|
||||
if (ret != 0) {
|
||||
printf("open %s failed, ret=%d\r\n", home_.c_str(), ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WT_CONNECTION* get_conn(void) const {
|
||||
return conn_;
|
||||
}
|
||||
|
||||
private:
|
||||
acl::string home_;
|
||||
WT_CONNECTION *conn_;
|
||||
};
|
||||
|
||||
class wdb_sess {
|
||||
public:
|
||||
wdb_sess(wdb& db)
|
||||
: db_(db)
|
||||
, session_(NULL)
|
||||
, cursor_(NULL) {}
|
||||
|
||||
~wdb_sess(void) {}
|
||||
|
||||
bool open(void) {
|
||||
bool ret = db_.get_conn()->open_session(db_.get_conn(),
|
||||
NULL, NULL, &session_);
|
||||
if (ret != 0) {
|
||||
printf("open session failed, ret=%d\r\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = session_->create(session_, "table:access",
|
||||
"key_format=S, value_format=S");
|
||||
if (ret != 0) {
|
||||
printf("create session failed, ret=%d\r\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = session_->open_cursor(session_, "table:access",
|
||||
NULL, NULL, &cursor_);
|
||||
if (ret != 0) {
|
||||
printf("create table failed, ret=%d\r\n", ret);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool add(const char* key, const char* value) {
|
||||
assert(cursor_);
|
||||
cursor_->set_key(cursor_, key);
|
||||
cursor_->set_value(cursor_, value);
|
||||
int ret = cursor_->insert(cursor_);
|
||||
if (ret != 0) {
|
||||
printf("insert %s %s failed, ret=%d\r\n", key, value, ret);
|
||||
return false;
|
||||
}
|
||||
cursor_->reset(cursor_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get(const char* key, acl::string& value) {
|
||||
assert(cursor_);
|
||||
cursor_->set_key(cursor_, key);
|
||||
int ret = cursor_->search(cursor_);
|
||||
if (ret != 0) {
|
||||
printf("search %s failed, ret=%d\r\n", key, ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* v;
|
||||
ret = cursor_->get_value(cursor_, &v);
|
||||
if (ret != 0) {
|
||||
printf("get_value %s failed, ret=%d\r\n", key, ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
value = v;
|
||||
cursor_->reset(cursor_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool del(const char* key) {
|
||||
assert(cursor_);
|
||||
cursor_->set_key(cursor_, key);
|
||||
int ret = cursor_->remove(cursor_);
|
||||
if (ret != 0) {
|
||||
printf("remove %s failed, ret=%d\r\n", key, ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
cursor_->reset(cursor_);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
wdb& db_;
|
||||
WT_SESSION *session_;
|
||||
WT_CURSOR *cursor_;
|
||||
};
|
||||
|
||||
class db_thread : public acl::thread {
|
||||
public:
|
||||
db_thread(int id, wdb& db, const char* action, int max)
|
||||
: id_(id), db_(db), action_(action), max_(max) {}
|
||||
|
||||
~db_thread(void) {}
|
||||
|
||||
private:
|
||||
// @override
|
||||
void* run(void) {
|
||||
wdb_sess sess(db_);
|
||||
if (sess.open() == false) {
|
||||
printf("open db session failed\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (action_ == "add") {
|
||||
add(sess, max_);
|
||||
} else if (action_ == "get") {
|
||||
get(sess, max_);
|
||||
} else if (action_ == "del") {
|
||||
del(sess, max_);
|
||||
} else {
|
||||
printf("invalid action=%s\r\n", action_.c_str());
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void add(wdb_sess& sess, long long max) {
|
||||
acl::string key, value;
|
||||
long long i, n;
|
||||
|
||||
struct timeval begin;
|
||||
gettimeofday(&begin, NULL);
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%lld", id_, i);
|
||||
value.format("value-%lld", i);
|
||||
bool ret = sess.add(key.c_str(), value.c_str());
|
||||
if (!ret) {
|
||||
printf("add failed, key=%s, value=%s\r\n",
|
||||
key.c_str(), value.c_str());
|
||||
break;
|
||||
}
|
||||
n = ++__count;
|
||||
if (i % __inter == 0) {
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), "i=%lld, count=%lld, value=%s",
|
||||
i, n, value.c_str());
|
||||
acl::meter_time(__FILE__, __LINE__, buf);
|
||||
}
|
||||
}
|
||||
|
||||
struct timeval end;
|
||||
gettimeofday(&end, NULL);
|
||||
double spent = acl::stamp_sub(end, begin);
|
||||
double speed = (i * 1000) / ( spent > 1 ? spent : 1);
|
||||
printf("add over, n=%lld, spent=%.2f seconds, speed=%.2f\r\n",
|
||||
i, spent / 1000, speed);
|
||||
}
|
||||
|
||||
void get(wdb_sess& sess, long long max) {
|
||||
acl::string key, value;
|
||||
long long i;
|
||||
long long n, j = 0, k = max - 1;
|
||||
|
||||
struct timeval begin;
|
||||
gettimeofday(&begin, NULL);
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
if (i % 2 == 0) {
|
||||
key.format("key-%d-%lld", id_, j++);
|
||||
} else {
|
||||
key.format("key-%d-%lld", id_, k--);
|
||||
}
|
||||
|
||||
bool ret = sess.get(key.c_str(), value);
|
||||
if (!ret) {
|
||||
printf("Get failed, key=%s\r\n", key.c_str());
|
||||
break;
|
||||
} else if (i < 10) {
|
||||
printf("key=%s, value=%s\r\n",
|
||||
key.c_str(), value.c_str());
|
||||
}
|
||||
n = ++__count;
|
||||
if (i % __inter == 0) {
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), "i=%lld, count=%lld, value=%s",
|
||||
i, n, value.c_str());
|
||||
acl::meter_time(__FILE__, __LINE__, buf);
|
||||
}
|
||||
}
|
||||
|
||||
struct timeval end;
|
||||
gettimeofday(&end, NULL);
|
||||
double spent = acl::stamp_sub(end, begin);
|
||||
double speed = (i * 1000) / ( spent > 1 ? spent : 1);
|
||||
printf("get over, n=%lld, spend=%.2f seconds, speed=%.2f\r\n",
|
||||
i, spent / 1000, speed);
|
||||
}
|
||||
|
||||
void del(wdb_sess& sess, long long max) {
|
||||
acl::string key;
|
||||
long long i;
|
||||
for (i = 0; i < max; i++) {
|
||||
key.format("key-%d-%lld", id_, i);
|
||||
bool ret = sess.del(key.c_str());
|
||||
if (!ret) {
|
||||
printf("Del failed, key=%s\r\n", key.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("del over, n=%lld\r\n", i);
|
||||
}
|
||||
|
||||
private:
|
||||
int id_;
|
||||
wdb& db_;
|
||||
acl::string action_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
static void usage(const char* procname)
|
||||
{
|
||||
printf("usage: %s -h [help]\r\n"
|
||||
" -c threads_count\r\n"
|
||||
" -a action[default: get, add|get|del]\r\n"
|
||||
" -n max_loop\r\n"
|
||||
" -i inter\r\n"
|
||||
, procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
const char* dbpath = "./db";
|
||||
int ch, max = 1000, nthread = 1;
|
||||
acl::string action("get");
|
||||
|
||||
while ((ch = getopt(argc, argv, "hn:a:c:i:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 'n':
|
||||
max = atoi(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
action = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
nthread = atoi(optarg);
|
||||
break;
|
||||
case 'i':
|
||||
__inter = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
acl::string path;
|
||||
path << dbpath;
|
||||
wdb db(path);
|
||||
if (!db.open()) {
|
||||
printf("open db(%s) error\r\n", dbpath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<acl::thread*> threads;
|
||||
for (int i = 0; i < nthread; i++) {
|
||||
acl::thread* thr = new db_thread(i, db, action, max);
|
||||
threads.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = threads.begin();
|
||||
it != threads.end(); ++it) {
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,47 +1,47 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#define BOX acl::mbox
|
||||
//#define BOX acl::tbox
|
||||
//#define BOX acl::tbox_array
|
||||
|
||||
class producer : public acl::thread
|
||||
{
|
||||
public:
|
||||
producer(BOX<int>& box, int max) : box_(box), max_(max) {}
|
||||
~producer(void) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
for (int i = 0; i < max_; i++) {
|
||||
int* n = new int;
|
||||
*n = i;
|
||||
box_.push(n);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
BOX<int>& box_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int max = 50000000;
|
||||
BOX<int> box;
|
||||
|
||||
producer thr(box, max);
|
||||
thr.start();
|
||||
|
||||
for (int i = 0; i < max; i++) {
|
||||
int* n = box.pop();
|
||||
assert(*n == i);
|
||||
delete n;
|
||||
}
|
||||
|
||||
printf("All over, max=%d\r\n", max);
|
||||
thr.wait();
|
||||
return 0;
|
||||
}
|
||||
#include "stdafx.h"
|
||||
|
||||
#define BOX acl::mbox
|
||||
//#define BOX acl::tbox
|
||||
//#define BOX acl::tbox_array
|
||||
|
||||
class producer : public acl::thread
|
||||
{
|
||||
public:
|
||||
producer(BOX<int>& box, int max) : box_(box), max_(max) {}
|
||||
~producer(void) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
for (int i = 0; i < max_; i++) {
|
||||
int* n = new int;
|
||||
*n = i;
|
||||
box_.push(n);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
BOX<int>& box_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int max = 50000000;
|
||||
BOX<int> box;
|
||||
|
||||
producer thr(box, max);
|
||||
thr.start();
|
||||
|
||||
for (int i = 0; i < max; i++) {
|
||||
int* n = box.pop();
|
||||
assert(*n == i);
|
||||
delete n;
|
||||
}
|
||||
|
||||
printf("All over, max=%d\r\n", max);
|
||||
thr.wait();
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,112 +1,112 @@
|
||||
#include "stdafx.h"
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
class client : public acl::thread
|
||||
{
|
||||
public:
|
||||
client(const char* addr) : addr_(addr) {}
|
||||
~client(void) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
acl::socket_stream conn;
|
||||
if (!conn.open(addr_, 10, 10)) {
|
||||
printf("%ld: connect %s error %s\r\n",
|
||||
acl::thread::self(), addr_.c_str(),
|
||||
acl::last_serror());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void) conn.set_tcp_solinger(true, 0);
|
||||
|
||||
printf("connect %s ok, my addr=%s\r\n",
|
||||
addr_.c_str(), conn.get_local(true));
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (conn.format("thread-%ld: hello world\r\n",
|
||||
acl::thread::self()) == -1) {
|
||||
|
||||
printf("write to %s error %s\r\n",
|
||||
addr_.c_str(), acl::last_serror());
|
||||
break;
|
||||
}
|
||||
acl::string buf;
|
||||
if (!conn.gets(buf)) {
|
||||
printf("gets from %s error %s\r\n",
|
||||
addr_.c_str(), acl::last_serror());
|
||||
break;
|
||||
} else {
|
||||
printf("%ld: %s\r\n", acl::thread::self(),
|
||||
buf.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
printf("sleep 2 seconds\r\n");
|
||||
sleep(2);
|
||||
printf("disconnect from %s now\r\n", addr_.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
acl::string addr_;
|
||||
};
|
||||
|
||||
static void add_servers(std::vector<acl::string>& servers, const char* s)
|
||||
{
|
||||
acl::string buf(s);
|
||||
const std::vector<acl::string>& tokens = buf.split2(",; \t");
|
||||
|
||||
for (std::vector<acl::string>::const_iterator cit = tokens.begin();
|
||||
cit != tokens.end(); ++cit) {
|
||||
|
||||
servers.push_back(*cit);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(const char* procname)
|
||||
{
|
||||
printf("usage: %s -h [help] -s server_list\r\n", procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std::vector<acl::string> addrs;
|
||||
int ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "hs:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 's':
|
||||
add_servers(addrs, optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (addrs.empty()) {
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<acl::thread*> threads;
|
||||
|
||||
for (std::vector<acl::string>::const_iterator cit = addrs.begin();
|
||||
cit != addrs.end(); ++cit) {
|
||||
|
||||
acl::thread* thr = new client(*cit);
|
||||
threads.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = threads.begin();
|
||||
it != threads.end(); ++it) {
|
||||
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#include "stdafx.h"
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
class client : public acl::thread
|
||||
{
|
||||
public:
|
||||
client(const char* addr) : addr_(addr) {}
|
||||
~client(void) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
acl::socket_stream conn;
|
||||
if (!conn.open(addr_, 10, 10)) {
|
||||
printf("%ld: connect %s error %s\r\n",
|
||||
acl::thread::self(), addr_.c_str(),
|
||||
acl::last_serror());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void) conn.set_tcp_solinger(true, 0);
|
||||
|
||||
printf("connect %s ok, my addr=%s\r\n",
|
||||
addr_.c_str(), conn.get_local(true));
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (conn.format("thread-%ld: hello world\r\n",
|
||||
acl::thread::self()) == -1) {
|
||||
|
||||
printf("write to %s error %s\r\n",
|
||||
addr_.c_str(), acl::last_serror());
|
||||
break;
|
||||
}
|
||||
acl::string buf;
|
||||
if (!conn.gets(buf)) {
|
||||
printf("gets from %s error %s\r\n",
|
||||
addr_.c_str(), acl::last_serror());
|
||||
break;
|
||||
} else {
|
||||
printf("%ld: %s\r\n", acl::thread::self(),
|
||||
buf.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
printf("sleep 2 seconds\r\n");
|
||||
sleep(2);
|
||||
printf("disconnect from %s now\r\n", addr_.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
acl::string addr_;
|
||||
};
|
||||
|
||||
static void add_servers(std::vector<acl::string>& servers, const char* s)
|
||||
{
|
||||
acl::string buf(s);
|
||||
const std::vector<acl::string>& tokens = buf.split2(",; \t");
|
||||
|
||||
for (std::vector<acl::string>::const_iterator cit = tokens.begin();
|
||||
cit != tokens.end(); ++cit) {
|
||||
|
||||
servers.push_back(*cit);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(const char* procname)
|
||||
{
|
||||
printf("usage: %s -h [help] -s server_list\r\n", procname);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std::vector<acl::string> addrs;
|
||||
int ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "hs:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 's':
|
||||
add_servers(addrs, optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (addrs.empty()) {
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<acl::thread*> threads;
|
||||
|
||||
for (std::vector<acl::string>::const_iterator cit = addrs.begin();
|
||||
cit != addrs.end(); ++cit) {
|
||||
|
||||
acl::thread* thr = new client(*cit);
|
||||
threads.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = threads.begin();
|
||||
it != threads.end(); ++it) {
|
||||
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ int main(int argc, char* argv[])
|
||||
case 'f':
|
||||
filepath = optarg;
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,49 +1,49 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#if 1
|
||||
#define TBOX acl::tbox_array
|
||||
#else
|
||||
#define TBOX acl::tbox
|
||||
#endif
|
||||
|
||||
class producer : public acl::thread
|
||||
{
|
||||
public:
|
||||
producer(TBOX<int>& box, int max) : box_(box), max_(max) {}
|
||||
~producer(void) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
for (int i = 0; i < max_; i++) {
|
||||
int* n = new int;
|
||||
*n = i;
|
||||
box_.push(n, true);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
TBOX<int>& box_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int max = 50000000;
|
||||
TBOX<int> box;
|
||||
|
||||
producer thr(box, max);
|
||||
thr.start();
|
||||
|
||||
for (int i = 0; i < max; i++) {
|
||||
int* n = box.pop();
|
||||
assert(*n == i);
|
||||
delete n;
|
||||
}
|
||||
|
||||
printf("All over, max=%d\r\n", max);
|
||||
thr.wait();
|
||||
return 0;
|
||||
}
|
||||
#include "stdafx.h"
|
||||
|
||||
#if 1
|
||||
#define TBOX acl::tbox_array
|
||||
#else
|
||||
#define TBOX acl::tbox
|
||||
#endif
|
||||
|
||||
class producer : public acl::thread
|
||||
{
|
||||
public:
|
||||
producer(TBOX<int>& box, int max) : box_(box), max_(max) {}
|
||||
~producer(void) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
for (int i = 0; i < max_; i++) {
|
||||
int* n = new int;
|
||||
*n = i;
|
||||
box_.push(n, true);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
TBOX<int>& box_;
|
||||
int max_;
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int max = 50000000;
|
||||
TBOX<int> box;
|
||||
|
||||
producer thr(box, max);
|
||||
thr.start();
|
||||
|
||||
for (int i = 0; i < max; i++) {
|
||||
int* n = box.pop();
|
||||
assert(*n == i);
|
||||
delete n;
|
||||
}
|
||||
|
||||
printf("All over, max=%d\r\n", max);
|
||||
thr.wait();
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,83 +1,83 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#if 0
|
||||
#define TBOX acl::tbox_array
|
||||
#else
|
||||
#define TBOX acl::tbox
|
||||
#endif
|
||||
|
||||
class producer : public acl::thread_job
|
||||
{
|
||||
public:
|
||||
producer(TBOX<int>& box) : box_(box) {}
|
||||
|
||||
private:
|
||||
~producer(void) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
int* n = new int;
|
||||
*n = 100;
|
||||
box_.push(n, true);
|
||||
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
TBOX<int>& box_;
|
||||
};
|
||||
|
||||
class consumer : public acl::thread
|
||||
{
|
||||
public:
|
||||
consumer(acl::thread_pool& threads, int max)
|
||||
: threads_(threads), max_(max) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
for (int i = 0; i < max_; i++) {
|
||||
TBOX<int> box;
|
||||
acl::thread_job* job = new producer(box);
|
||||
threads_.execute(job);
|
||||
int* n = box.pop();
|
||||
delete n;
|
||||
}
|
||||
|
||||
printf("consumer-%ld finish\r\n", acl::thread::self());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
acl::thread_pool& threads_;
|
||||
int max_;
|
||||
~consumer(void) {}
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
acl::thread_pool threads;
|
||||
threads.set_limit(500);
|
||||
threads.start();
|
||||
|
||||
int nconsumers = 10, max_loop = 1000000;
|
||||
std::vector<acl::thread*> consumers;
|
||||
for (int i = 0; i < nconsumers; i++) {
|
||||
acl::thread* thr = new consumer(threads, max_loop);
|
||||
consumers.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = consumers.begin();
|
||||
it != consumers.end(); ++it) {
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
|
||||
threads.stop();
|
||||
|
||||
printf("All over: count=%d\r\n", nconsumers * max_loop);
|
||||
return 0;
|
||||
}
|
||||
#include "stdafx.h"
|
||||
|
||||
#if 0
|
||||
#define TBOX acl::tbox_array
|
||||
#else
|
||||
#define TBOX acl::tbox
|
||||
#endif
|
||||
|
||||
class producer : public acl::thread_job
|
||||
{
|
||||
public:
|
||||
producer(TBOX<int>& box) : box_(box) {}
|
||||
|
||||
private:
|
||||
~producer(void) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
int* n = new int;
|
||||
*n = 100;
|
||||
box_.push(n, true);
|
||||
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
TBOX<int>& box_;
|
||||
};
|
||||
|
||||
class consumer : public acl::thread
|
||||
{
|
||||
public:
|
||||
consumer(acl::thread_pool& threads, int max)
|
||||
: threads_(threads), max_(max) {}
|
||||
|
||||
protected:
|
||||
void* run(void)
|
||||
{
|
||||
for (int i = 0; i < max_; i++) {
|
||||
TBOX<int> box;
|
||||
acl::thread_job* job = new producer(box);
|
||||
threads_.execute(job);
|
||||
int* n = box.pop();
|
||||
delete n;
|
||||
}
|
||||
|
||||
printf("consumer-%ld finish\r\n", acl::thread::self());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
acl::thread_pool& threads_;
|
||||
int max_;
|
||||
~consumer(void) {}
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
acl::thread_pool threads;
|
||||
threads.set_limit(500);
|
||||
threads.start();
|
||||
|
||||
int nconsumers = 10, max_loop = 1000000;
|
||||
std::vector<acl::thread*> consumers;
|
||||
for (int i = 0; i < nconsumers; i++) {
|
||||
acl::thread* thr = new consumer(threads, max_loop);
|
||||
consumers.push_back(thr);
|
||||
thr->start();
|
||||
}
|
||||
|
||||
for (std::vector<acl::thread*>::iterator it = consumers.begin();
|
||||
it != consumers.end(); ++it) {
|
||||
(*it)->wait();
|
||||
delete *it;
|
||||
}
|
||||
|
||||
threads.stop();
|
||||
|
||||
printf("All over: count=%d\r\n", nconsumers * max_loop);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,39 +1,39 @@
|
||||
#include "stdafx.h"
|
||||
#include "fiber/fiber_define.h"
|
||||
#include "fiber.h"
|
||||
#include "msg.h"
|
||||
#include "iostuff.h"
|
||||
|
||||
int read_wait(socket_t fd, int delay)
|
||||
{
|
||||
struct pollfd fds;
|
||||
|
||||
fds.events = POLLIN;
|
||||
fds.fd = fd;
|
||||
|
||||
for (;;) {
|
||||
switch (acl_fiber_poll(&fds, 1, delay)) {
|
||||
#ifdef SYS_WIN
|
||||
case SOCKET_ERROR:
|
||||
#else
|
||||
case -1:
|
||||
#endif
|
||||
if (acl_fiber_last_error() == FIBER_EINTR) {
|
||||
continue;
|
||||
}
|
||||
return -1;
|
||||
case 0:
|
||||
acl_fiber_set_error(FIBER_ETIMEDOUT);
|
||||
return -1;
|
||||
default:
|
||||
if ((fds.revents & POLLIN)) {
|
||||
return 0;
|
||||
}
|
||||
if (fds.revents & (POLLHUP | POLLERR | POLLNVAL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "stdafx.h"
|
||||
#include "fiber/fiber_define.h"
|
||||
#include "fiber.h"
|
||||
#include "msg.h"
|
||||
#include "iostuff.h"
|
||||
|
||||
int read_wait(socket_t fd, int delay)
|
||||
{
|
||||
struct pollfd fds;
|
||||
|
||||
fds.events = POLLIN;
|
||||
fds.fd = fd;
|
||||
|
||||
for (;;) {
|
||||
switch (acl_fiber_poll(&fds, 1, delay)) {
|
||||
#ifdef SYS_WIN
|
||||
case SOCKET_ERROR:
|
||||
#else
|
||||
case -1:
|
||||
#endif
|
||||
if (acl_fiber_last_error() == FIBER_EINTR) {
|
||||
continue;
|
||||
}
|
||||
return -1;
|
||||
case 0:
|
||||
acl_fiber_set_error(FIBER_ETIMEDOUT);
|
||||
return -1;
|
||||
default:
|
||||
if ((fds.revents & POLLIN)) {
|
||||
return 0;
|
||||
}
|
||||
if (fds.revents & (POLLHUP | POLLERR | POLLNVAL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,34 +1,34 @@
|
||||
#ifndef __RESOLVER_INCLUDE_H__
|
||||
#define __RESOLVER_INCLUDE_H__
|
||||
|
||||
#include "common/argv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct HOST_LOCAL {
|
||||
char ipv4[64];
|
||||
char ipv6[64];
|
||||
} HOST_LOCAL;
|
||||
|
||||
typedef struct SERVICE_PORT {
|
||||
char name[128];
|
||||
unsigned short port;
|
||||
ARGV *transports;
|
||||
} SERVICE_PORT;
|
||||
|
||||
void resolver_init_once(void);
|
||||
struct addrinfo *resolver_getaddrinfo(const char *name, const char *service,
|
||||
const struct addrinfo* hints);
|
||||
void resolver_freeaddrinfo(struct addrinfo *res);
|
||||
struct addrinfo *resolver_addrinfo_alloc(const struct sockaddr *sa);
|
||||
|
||||
unsigned short get_service_port(const char *name);
|
||||
const HOST_LOCAL *find_from_localhost(const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifndef __RESOLVER_INCLUDE_H__
|
||||
#define __RESOLVER_INCLUDE_H__
|
||||
|
||||
#include "common/argv.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct HOST_LOCAL {
|
||||
char ipv4[64];
|
||||
char ipv6[64];
|
||||
} HOST_LOCAL;
|
||||
|
||||
typedef struct SERVICE_PORT {
|
||||
char name[128];
|
||||
unsigned short port;
|
||||
ARGV *transports;
|
||||
} SERVICE_PORT;
|
||||
|
||||
void resolver_init_once(void);
|
||||
struct addrinfo *resolver_getaddrinfo(const char *name, const char *service,
|
||||
const struct addrinfo* hints);
|
||||
void resolver_freeaddrinfo(struct addrinfo *res);
|
||||
struct addrinfo *resolver_addrinfo_alloc(const struct sockaddr *sa);
|
||||
|
||||
unsigned short get_service_port(const char *name);
|
||||
const HOST_LOCAL *find_from_localhost(const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,15 +1,15 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/25.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
// AppDelegate.h
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/25.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
@ -1,29 +1,29 @@
|
||||
//
|
||||
// FiberClient.cpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "fiber/libfiber.hpp"
|
||||
#include "FiberClient.hpp"
|
||||
|
||||
void FiberClient::run(void) {
|
||||
printf("FiberClient run, fd=%d\r\n", fd_);
|
||||
char buf[8192];
|
||||
while (true) {
|
||||
ssize_t ret = read(fd_, buf, sizeof(buf));
|
||||
if (ret <= 0) {
|
||||
break;
|
||||
}
|
||||
if (write(fd_, buf, ret) <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("Close client fd=%d\r\n", fd_);
|
||||
close(fd_);
|
||||
delete this;
|
||||
}
|
||||
//
|
||||
// FiberClient.cpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "fiber/libfiber.hpp"
|
||||
#include "FiberClient.hpp"
|
||||
|
||||
void FiberClient::run(void) {
|
||||
printf("FiberClient run, fd=%d\r\n", fd_);
|
||||
char buf[8192];
|
||||
while (true) {
|
||||
ssize_t ret = read(fd_, buf, sizeof(buf));
|
||||
if (ret <= 0) {
|
||||
break;
|
||||
}
|
||||
if (write(fd_, buf, ret) <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("Close client fd=%d\r\n", fd_);
|
||||
close(fd_);
|
||||
delete this;
|
||||
}
|
||||
|
@ -1,26 +1,26 @@
|
||||
//
|
||||
// FiberClient.hpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef FiberClient_hpp
|
||||
#define FiberClient_hpp
|
||||
|
||||
class FiberClient : public acl::fiber {
|
||||
public:
|
||||
FiberClient(int fd) : fd_(fd) {}
|
||||
|
||||
protected:
|
||||
// @override
|
||||
void run(void);
|
||||
|
||||
~FiberClient(void) {}
|
||||
|
||||
private:
|
||||
int fd_;
|
||||
};
|
||||
|
||||
#endif /* FiberClient_hpp */
|
||||
//
|
||||
// FiberClient.hpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef FiberClient_hpp
|
||||
#define FiberClient_hpp
|
||||
|
||||
class FiberClient : public acl::fiber {
|
||||
public:
|
||||
FiberClient(int fd) : fd_(fd) {}
|
||||
|
||||
protected:
|
||||
// @override
|
||||
void run(void);
|
||||
|
||||
~FiberClient(void) {}
|
||||
|
||||
private:
|
||||
int fd_;
|
||||
};
|
||||
|
||||
#endif /* FiberClient_hpp */
|
||||
|
@ -1,78 +1,78 @@
|
||||
//
|
||||
// FiberServer.cpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "fiber/libfiber.hpp"
|
||||
#include "FiberClient.hpp"
|
||||
#include "FiberServer.hpp"
|
||||
|
||||
FiberServer::FiberServer(const char* ip, int port)
|
||||
: ip_(ip), port_(port), lfd_(-1) {}
|
||||
|
||||
int FiberServer::BindAndrListen(const char *ip, int port) {
|
||||
int fd;
|
||||
int on;
|
||||
struct sockaddr_in sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons(port);
|
||||
sa.sin_addr.s_addr = inet_addr(ip);
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
printf("create socket error, %s\r\n", acl::fiber::last_serror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) {
|
||||
printf("setsockopt error %s\r\n", acl::fiber::last_serror());
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &sa, sizeof(struct sockaddr)) < 0) {
|
||||
printf("bind error %s\r\n", acl::fiber::last_serror());
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(fd, 1024) < 0) {
|
||||
printf("listen error %s\r\n", acl::fiber::last_serror());
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void FiberServer::run(void) {
|
||||
lfd_ = BindAndrListen(ip_.c_str(), port_);
|
||||
if (lfd_ == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("listen %s:%d ok\r\n", ip_.c_str(), port_);
|
||||
|
||||
while (true) {
|
||||
struct sockaddr_in sa;
|
||||
size_t len = sizeof(sa);
|
||||
int fd = accept(lfd_, (struct sockaddr *)& sa, (socklen_t *)& len);
|
||||
if (fd == -1) {
|
||||
printf("accept error\r\n");
|
||||
break;
|
||||
}
|
||||
printf("Accept on fd=%d\r\n", fd);
|
||||
FiberClient* fb = new FiberClient(fd);
|
||||
fb->start();
|
||||
}
|
||||
close(lfd_);
|
||||
delete this;
|
||||
}
|
||||
//
|
||||
// FiberServer.cpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "fiber/libfiber.hpp"
|
||||
#include "FiberClient.hpp"
|
||||
#include "FiberServer.hpp"
|
||||
|
||||
FiberServer::FiberServer(const char* ip, int port)
|
||||
: ip_(ip), port_(port), lfd_(-1) {}
|
||||
|
||||
int FiberServer::BindAndrListen(const char *ip, int port) {
|
||||
int fd;
|
||||
int on;
|
||||
struct sockaddr_in sa;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons(port);
|
||||
sa.sin_addr.s_addr = inet_addr(ip);
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
printf("create socket error, %s\r\n", acl::fiber::last_serror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) {
|
||||
printf("setsockopt error %s\r\n", acl::fiber::last_serror());
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &sa, sizeof(struct sockaddr)) < 0) {
|
||||
printf("bind error %s\r\n", acl::fiber::last_serror());
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(fd, 1024) < 0) {
|
||||
printf("listen error %s\r\n", acl::fiber::last_serror());
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void FiberServer::run(void) {
|
||||
lfd_ = BindAndrListen(ip_.c_str(), port_);
|
||||
if (lfd_ == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("listen %s:%d ok\r\n", ip_.c_str(), port_);
|
||||
|
||||
while (true) {
|
||||
struct sockaddr_in sa;
|
||||
size_t len = sizeof(sa);
|
||||
int fd = accept(lfd_, (struct sockaddr *)& sa, (socklen_t *)& len);
|
||||
if (fd == -1) {
|
||||
printf("accept error\r\n");
|
||||
break;
|
||||
}
|
||||
printf("Accept on fd=%d\r\n", fd);
|
||||
FiberClient* fb = new FiberClient(fd);
|
||||
fb->start();
|
||||
}
|
||||
close(lfd_);
|
||||
delete this;
|
||||
}
|
||||
|
@ -1,32 +1,32 @@
|
||||
//
|
||||
// FiberServer.hpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef FiberServer_hpp
|
||||
#define FiberServer_hpp
|
||||
|
||||
#include <string>
|
||||
|
||||
class FiberServer : public acl::fiber {
|
||||
public:
|
||||
FiberServer(const char* ip, int port);
|
||||
|
||||
protected:
|
||||
// @override
|
||||
void run(void);
|
||||
|
||||
~FiberServer(void) {}
|
||||
|
||||
private:
|
||||
std::string ip_;
|
||||
int port_;
|
||||
int lfd_;
|
||||
|
||||
int BindAndrListen(const char *ip, int port);
|
||||
};
|
||||
|
||||
#endif /* FiberServer_hpp */
|
||||
//
|
||||
// FiberServer.hpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef FiberServer_hpp
|
||||
#define FiberServer_hpp
|
||||
|
||||
#include <string>
|
||||
|
||||
class FiberServer : public acl::fiber {
|
||||
public:
|
||||
FiberServer(const char* ip, int port);
|
||||
|
||||
protected:
|
||||
// @override
|
||||
void run(void);
|
||||
|
||||
~FiberServer(void) {}
|
||||
|
||||
private:
|
||||
std::string ip_;
|
||||
int port_;
|
||||
int lfd_;
|
||||
|
||||
int BindAndrListen(const char *ip, int port);
|
||||
};
|
||||
|
||||
#endif /* FiberServer_hpp */
|
||||
|
@ -1,18 +1,18 @@
|
||||
//
|
||||
// FiberTest.h
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef FiberTest_h
|
||||
#define FiberTest_h
|
||||
|
||||
@interface FiberTest : NSObject
|
||||
|
||||
-(void) Start;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* FiberTest_h */
|
||||
//
|
||||
// FiberTest.h
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef FiberTest_h
|
||||
#define FiberTest_h
|
||||
|
||||
@interface FiberTest : NSObject
|
||||
|
||||
-(void) Start;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* FiberTest_h */
|
||||
|
@ -1,26 +1,26 @@
|
||||
//
|
||||
// FiberTest.cpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#include <thread>
|
||||
#include "fiber/libfiber.hpp"
|
||||
#include "FiberServer.hpp"
|
||||
#include "FiberThread.hpp"
|
||||
|
||||
static void ThreadRun(void) {
|
||||
const char* ip = "127.0.0.1";
|
||||
int port = 8192;
|
||||
FiberServer* fb = new FiberServer(ip, port);
|
||||
fb->start();
|
||||
|
||||
acl::fiber::schedule();
|
||||
}
|
||||
|
||||
void StartThread(void) {
|
||||
std::thread* thread = new std::thread(ThreadRun);
|
||||
thread->detach();
|
||||
}
|
||||
//
|
||||
// FiberTest.cpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#include <thread>
|
||||
#include "fiber/libfiber.hpp"
|
||||
#include "FiberServer.hpp"
|
||||
#include "FiberThread.hpp"
|
||||
|
||||
static void ThreadRun(void) {
|
||||
const char* ip = "127.0.0.1";
|
||||
int port = 8192;
|
||||
FiberServer* fb = new FiberServer(ip, port);
|
||||
fb->start();
|
||||
|
||||
acl::fiber::schedule();
|
||||
}
|
||||
|
||||
void StartThread(void) {
|
||||
std::thread* thread = new std::thread(ThreadRun);
|
||||
thread->detach();
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
//
|
||||
// FiberTest.hpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef FiberTest_hpp
|
||||
#define FiberTest_hpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void StartThread(void);
|
||||
|
||||
#endif /* FiberTest_hpp */
|
||||
//
|
||||
// FiberTest.hpp
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/26.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef FiberTest_hpp
|
||||
#define FiberTest_hpp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void StartThread(void);
|
||||
|
||||
#endif /* FiberTest_hpp */
|
||||
|
@ -1,16 +1,16 @@
|
||||
//
|
||||
// SceneDelegate.h
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/25.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow * window;
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
// SceneDelegate.h
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/25.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow * window;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
//
|
||||
// ViewController.h
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/25.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ViewController : UIViewController
|
||||
|
||||
|
||||
@end
|
||||
|
||||
//
|
||||
// ViewController.h
|
||||
// fiber_server
|
||||
//
|
||||
// Created by shuxin zheng on 2020/9/25.
|
||||
// Copyright © 2020 acl. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ViewController : UIViewController
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user