use pthread_getspecific instead of __thread

This commit is contained in:
Cloud Wu
2014-04-24 17:55:43 +08:00
parent bd3aa3f3c5
commit bad9a5fc54
6 changed files with 52 additions and 14 deletions

View File

@@ -12,6 +12,12 @@ struct skynet_config {
const char * standalone; const char * standalone;
}; };
#define THREAD_WORKER 0
#define THREAD_MAIN 1
#define THREAD_SOCKET 2
#define THREAD_TIMER 3
#define THREAD_MONITOR 4
void skynet_start(struct skynet_config * config); void skynet_start(struct skynet_config * config);
#endif #endif

View File

@@ -2,6 +2,8 @@
#include "skynet_imp.h" #include "skynet_imp.h"
#include "skynet_env.h" #include "skynet_env.h"
#include "skynet_server.h"
#include "malloc_hook.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -87,6 +89,9 @@ main(int argc, char *argv[]) {
if (argc > 1) { if (argc > 1) {
config_file = argv[1]; config_file = argv[1];
} }
skynet_globalinit();
malloc_inithook();
skynet_env_init(); skynet_env_init();
sigign(); sigign();
@@ -129,6 +134,7 @@ main(int argc, char *argv[]) {
lua_close(L); lua_close(L);
skynet_start(&config); skynet_start(&config);
skynet_globalexit();
printf("skynet exit\n"); printf("skynet exit\n");

View File

@@ -8,6 +8,9 @@
#include "skynet_harbor.h" #include "skynet_harbor.h"
#include "skynet_env.h" #include "skynet_env.h"
#include "skynet_monitor.h" #include "skynet_monitor.h"
#include "skynet_imp.h"
#include <pthread.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
@@ -50,10 +53,10 @@ struct skynet_context {
struct skynet_node { struct skynet_node {
int total; int total;
uint32_t monitor_exit; uint32_t monitor_exit;
pthread_key_t handle_key;
}; };
static struct skynet_node G_NODE = { 0,0 }; static struct skynet_node G_NODE;
static __thread uint32_t handle_tls = 0xffffffff;
int int
skynet_context_total() { skynet_context_total() {
@@ -72,7 +75,8 @@ _context_dec() {
uint32_t uint32_t
skynet_current_handle(void) { skynet_current_handle(void) {
return handle_tls; void * handle = pthread_getspecific(G_NODE.handle_key);
return (uint32_t)(uintptr_t)handle;
} }
static void static void
@@ -199,13 +203,12 @@ static void
_dispatch_message(struct skynet_context *ctx, struct skynet_message *msg) { _dispatch_message(struct skynet_context *ctx, struct skynet_message *msg) {
assert(ctx->init); assert(ctx->init);
CHECKCALLING_BEGIN(ctx) CHECKCALLING_BEGIN(ctx)
handle_tls = ctx->handle; pthread_setspecific(G_NODE.handle_key, (void *)(uintptr_t)(ctx->handle));
int type = msg->sz >> HANDLE_REMOTE_SHIFT; int type = msg->sz >> HANDLE_REMOTE_SHIFT;
size_t sz = msg->sz & HANDLE_MASK; size_t sz = msg->sz & HANDLE_MASK;
if (!ctx->cb(ctx, ctx->cb_ud, type, msg->session, msg->source, msg->data, sz)) { if (!ctx->cb(ctx, ctx->cb_ud, type, msg->session, msg->source, msg->data, sz)) {
skynet_free(msg->data); skynet_free(msg->data);
} }
handle_tls = 0xffffffff;
CHECKCALLING_END(ctx) CHECKCALLING_END(ctx)
} }
@@ -590,3 +593,27 @@ skynet_context_send(struct skynet_context * ctx, void * msg, size_t sz, uint32_t
skynet_mq_push(ctx->queue, &smsg); skynet_mq_push(ctx->queue, &smsg);
} }
void
skynet_globalinit(void) {
G_NODE.total = 0;
G_NODE.monitor_exit = 0;
if (pthread_key_create(&G_NODE.handle_key, NULL)) {
fprintf(stderr, "pthread_key_create failed");
exit(1);
}
// set mainthread's key
skynet_initthread(THREAD_MAIN);
}
void
skynet_globalexit(void) {
pthread_key_delete(G_NODE.handle_key);
}
void
skynet_initthread(int m) {
uintptr_t v = (uint32_t)(-m);
pthread_setspecific(G_NODE.handle_key, (void *)v);
}

View File

@@ -21,4 +21,8 @@ int skynet_context_total();
void skynet_context_endless(uint32_t handle); // for monitor void skynet_context_endless(uint32_t handle); // for monitor
void skynet_globalinit(void);
void skynet_globalexit(void);
void skynet_initthread(int m);
#endif #endif

View File

@@ -50,6 +50,7 @@ wakeup(struct monitor *m, int busy) {
static void * static void *
_socket(void *p) { _socket(void *p) {
struct monitor * m = p; struct monitor * m = p;
skynet_initthread(THREAD_SOCKET);
for (;;) { for (;;) {
int r = skynet_socket_poll(); int r = skynet_socket_poll();
if (r==0) if (r==0)
@@ -81,6 +82,7 @@ _monitor(void *p) {
struct monitor * m = p; struct monitor * m = p;
int i; int i;
int n = m->count; int n = m->count;
skynet_initthread(THREAD_MONITOR);
for (;;) { for (;;) {
CHECK_ABORT CHECK_ABORT
for (i=0;i<n;i++) { for (i=0;i<n;i++) {
@@ -98,6 +100,7 @@ _monitor(void *p) {
static void * static void *
_timer(void *p) { _timer(void *p) {
struct monitor * m = p; struct monitor * m = p;
skynet_initthread(THREAD_TIMER);
for (;;) { for (;;) {
skynet_updatetime(); skynet_updatetime();
CHECK_ABORT CHECK_ABORT
@@ -117,6 +120,7 @@ _worker(void *p) {
int id = wp->id; int id = wp->id;
struct monitor *m = wp->m; struct monitor *m = wp->m;
struct skynet_monitor *sm = m->m[id]; struct skynet_monitor *sm = m->m[id];
skynet_initthread(THREAD_WORKER);
for (;;) { for (;;) {
if (skynet_context_message_dispatch(sm)) { if (skynet_context_message_dispatch(sm)) {
CHECK_ABORT CHECK_ABORT

View File

@@ -1,9 +0,0 @@
local skynet = require "skynet"
local log = require "log"
skynet.start(function()
log.Info("hello world")
skynet.exit()
end)