Esempio n. 1
0
static void php_swoole_dns_timeout_coro(swTimer *timer, swTimer_node *tnode)
{
    zval *retval = NULL;
    zval *zaddress;
    php_context *cxt = (php_context *) tnode->data;
    dns_request *req = (dns_request *) cxt->coro_params.value.ptr;

    SW_MAKE_STD_ZVAL(zaddress);

    dns_cache *cache = swHashMap_find(request_cache_map, Z_STRVAL_P(req->domain), Z_STRLEN_P(req->domain));
    if (cache != NULL && cache->update_time > (int64_t) swTimer_get_now_msec)
    {
        SW_ZVAL_STRINGL(zaddress, (*cache->zaddress).str, (*cache->zaddress).length, 1);
    }
    else
    {
        SW_ZVAL_STRING(zaddress, "", 1);
    }

    int ret = coro_resume(req->context, zaddress, &retval);
    if (ret > 0)
    {
        goto free_zdata;
    }

    if (retval != NULL)
    {
        sw_zval_ptr_dtor(&retval);
    }
    free_zdata:
    sw_zval_ptr_dtor(&zaddress);
    efree(req->context);
    req->useless = 1;

}
Esempio n. 2
0
static PHP_METHOD(swoole_coroutine_util, resume)
{
    char *id;
    int id_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE)
    {
        return;
    }

    swLinkedList *coros_list = swHashMap_find(defer_coros, id, id_len);
    if (coros_list == NULL)
    {
        swoole_php_fatal_error(E_WARNING, "Nothing can coroResume.");
        RETURN_FALSE;
    }

    php_context *context = swLinkedList_shift(coros_list);
    if (context == NULL)
    {
        swoole_php_fatal_error(E_WARNING, "Nothing can coroResume.");
        RETURN_FALSE;
    }

    SwooleG.main_reactor->defer(SwooleG.main_reactor, swoole_coroutine_util_resume, context);

    RETURN_TRUE;
}
Esempio n. 3
0
static PHP_METHOD(swoole_coroutine_util, suspend)
{
    char *id;
    int id_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",&id, &id_len) == FAILURE)
    {
        return;
    }

    swLinkedList *coros_list = swHashMap_find(defer_coros, id, id_len);
    if (coros_list == NULL)
    {
        coros_list = swLinkedList_new(2, NULL);
        if (coros_list == NULL)
        {
            RETURN_FALSE;
        }
        if (swHashMap_add(defer_coros, id, id_len, coros_list) == SW_ERR)
        {
            swLinkedList_free(coros_list);
            RETURN_FALSE;
        }
    }

    php_context *context = emalloc(sizeof(php_context));
    coro_save(context);
    if (swLinkedList_append(coros_list, (void *)context) == SW_ERR) {
        efree(context);
        RETURN_FALSE;
    }
    coro_yield();
}
Esempio n. 4
0
void* swoole_get_function(char *name, uint32_t length)
{
    if (!SwooleG.functions)
    {
        return NULL;
    }
    return swHashMap_find(SwooleG.functions, name, length);
}
Esempio n. 5
0
int swoole_add_function(const char *name, void* func)
{
    if (SwooleG.functions == NULL)
    {
        SwooleG.functions = swHashMap_new(64, NULL);
        if (SwooleG.functions == NULL)
        {
            return SW_ERR;
        }
    }
    if (swHashMap_find(SwooleG.functions, (char *) name, strlen(name)) != NULL)
    {
        swWarn("Function '%s' has already been added.", name);
        return SW_ERR;
    }
    return swHashMap_add(SwooleG.functions, (char *) name, strlen(name), func);
}
Esempio n. 6
0
static int swClient_inet_addr(swClient *cli, char *host, int port)
{
    struct hostent *host_entry;
    void *s_addr = NULL;

    if (cli->type == SW_SOCK_TCP || cli->type == SW_SOCK_UDP)
    {
        cli->server_addr.addr.inet_v4.sin_family = AF_INET;
        cli->server_addr.addr.inet_v4.sin_port = htons(port);
        cli->server_addr.len = sizeof(cli->server_addr.addr.inet_v4);
        s_addr = &cli->server_addr.addr.inet_v4.sin_addr.s_addr;

        if (inet_pton(AF_INET, host, s_addr))
        {
            return SW_OK;
        }
    }
    else if (cli->type == SW_SOCK_TCP6 || cli->type == SW_SOCK_UDP6)
    {
        cli->server_addr.addr.inet_v6.sin6_family = AF_INET6;
        cli->server_addr.addr.inet_v6.sin6_port = htons(port);
        cli->server_addr.len = sizeof(cli->server_addr.addr.inet_v6);
        s_addr = cli->server_addr.addr.inet_v6.sin6_addr.s6_addr;

        if (inet_pton(AF_INET6, host, s_addr))
        {
            return SW_OK;
        }
    }
    else if (cli->type == SW_SOCK_UNIX_STREAM || cli->type == SW_SOCK_UNIX_DGRAM)
    {
        cli->server_addr.addr.un.sun_family = AF_UNIX;
        strncpy(cli->server_addr.addr.un.sun_path, host, sizeof(cli->server_addr.addr.un.sun_path));
        cli->server_addr.len = sizeof(cli->server_addr.addr.un);
        return SW_OK;
    }

    if (!swoole_dns_cache)
    {
        swoole_dns_cache = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, free);
    }

    swDNS_cache *cache = swHashMap_find(swoole_dns_cache, host, strlen(host));
    if (cache == NULL)
    {
        if (cli->async)
        {
            swWarn("DNS lookup will block the process. Please use swoole_async_dns_lookup.");
        }
        if (!(host_entry = gethostbyname(host)))
        {
            swWarn("gethostbyname('%s') failed.", host);
            return SW_ERR;
        }
        if (host_entry->h_addrtype != AF_INET)
        {
            swWarn("Host lookup failed: Non AF_INET domain returned on AF_INET socket.");
            return 0;
        }
        cache = sw_malloc(sizeof(int) + host_entry->h_length);
        if (cache == NULL)
        {
            swWarn("malloc() failed.");
            memcpy(s_addr, host_entry->h_addr_list[0], host_entry->h_length);
            return SW_OK;
        }
        else
        {
            memcpy(cache->addr, host_entry->h_addr_list[0], host_entry->h_length);
            cache->length = host_entry->h_length;
        }
        swHashMap_add(swoole_dns_cache, host, strlen(host), cache);
    }
    memcpy(s_addr, cache->addr, cache->length);
    return SW_OK;
}
Esempio n. 7
0
/**
 * DNS lookup
 */
int swoole_gethostbyname(int flags, char *name, char *addr)
{
    SwooleGS->lock.lock(&SwooleGS->lock);
    swHashMap *cache_table;

    int __af = flags & (~SW_DNS_LOOKUP_CACHE_ONLY) & (~SW_DNS_LOOKUP_RANDOM);
    if (__af == AF_INET)
    {
        if (!swoole_dns_cache_v4)
        {
            swoole_dns_cache_v4 = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, free);
        }
        cache_table = swoole_dns_cache_v4;
    }
    else if (__af == AF_INET6)
    {
        if (!swoole_dns_cache_v6)
        {
            swoole_dns_cache_v6 = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, free);
        }
        cache_table = swoole_dns_cache_v6;
    }
    else
    {
        SwooleGS->lock.unlock(&SwooleGS->lock);
        return SW_ERR;
    }


    int name_length = strlen(name);
    int index = 0;
    swDNS_cache *cache = swHashMap_find(cache_table, name, name_length);
    if (cache == NULL && (flags & SW_DNS_LOOKUP_CACHE_ONLY))
    {
        SwooleGS->lock.unlock(&SwooleGS->lock);
        return SW_ERR;
    }

    if (cache == NULL)
    {
        struct hostent *host_entry;
        if (!(host_entry = gethostbyname2(name, __af)))
        {
            SwooleGS->lock.unlock(&SwooleGS->lock);
            return SW_ERR;
        }

        cache = sw_malloc(sizeof(swDNS_cache));
        if (cache == NULL)
        {
            SwooleGS->lock.unlock(&SwooleGS->lock);
            memcpy(addr, host_entry->h_addr_list[0], host_entry->h_length);
            return SW_OK;
        }

        bzero(cache, sizeof(swDNS_cache));
        int i = 0;
        for (i = 0; i < SW_DNS_LOOKUP_CACHE_SIZE; i++)
        {
            if (host_entry->h_addr_list[i] == NULL)
            {
                break;
            }
            if (__af == AF_INET)
            {
                memcpy(&cache->addr[i].v4, host_entry->h_addr_list[i], host_entry->h_length);
            }
            else
            {
                memcpy(&cache->addr[i].v6, host_entry->h_addr_list[i], host_entry->h_length);
            }
        }
        cache->number = i;
        cache->addr_length = host_entry->h_length;
        swHashMap_add(cache_table, name, name_length, cache);
    }
    SwooleGS->lock.unlock(&SwooleGS->lock);
    if (flags & SW_DNS_LOOKUP_RANDOM)
    {
        index = rand() % cache->number;
    }
    if (__af == AF_INET)
    {
        memcpy(addr, &cache->addr[index].v4, cache->addr_length);
    }
    else
    {
        memcpy(addr, &cache->addr[index].v6, cache->addr_length);
    }
    return SW_OK;
}
Esempio n. 8
0
static void php_swoole_dns_callback_coro(char *domain, swDNSResolver_result *result, void *data)
{
    SWOOLE_GET_TSRMLS;
    dns_request *req = data;
    zval *retval = NULL;

    zval *zaddress;
    char *address;
    SW_MAKE_STD_ZVAL(zaddress);
    if (result->num > 0)
    {
        if (SwooleG.dns_lookup_random)
        {
            address = result->hosts[rand() % result->num].address;
        }
        else
        {
            address = result->hosts[0].address;
        }

        SW_ZVAL_STRING(zaddress, address, 1);
    }
    else
    {
        SW_ZVAL_STRING(zaddress, "", 1);
    }

    //update cache
    dns_cache *cache = swHashMap_find(request_cache_map, Z_STRVAL_P(req->domain), Z_STRLEN_P(req->domain));
    if (cache == NULL )
    {
        cache = emalloc(sizeof(dns_cache));
        swHashMap_add(request_cache_map, Z_STRVAL_P(req->domain), Z_STRLEN_P(req->domain), cache);
        cache->zaddress = swString_new(20);
    }

    swString_write_ptr(cache->zaddress, 0, Z_STRVAL_P(zaddress), Z_STRLEN_P(zaddress));

    cache->update_time = (int64_t) swTimer_get_now_msec + (int64_t) (SwooleG.dns_cache_refresh_time * 1000);

    //timeout
    if (req->timer)
    {
        swTimer_del(&SwooleG.timer, req->timer);
        req->timer = NULL;
    }
    if (req->useless)
    {
        efree(req);
        return;
    }

    int ret = coro_resume(req->context, zaddress, &retval);
    if (ret > 0)
    {
        goto free_zdata;
    }

    if (retval != NULL)
    {
        sw_zval_ptr_dtor(&retval);
    }
    //说明已经yield走了
    free_zdata:
    // free 上下文
    sw_zval_ptr_dtor(&zaddress);
    efree(req->context);
    efree(req);
}
Esempio n. 9
0
static PHP_METHOD(swoole_module, __call)
{
    zval *params;
    char *name;
    zend_size_t name_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &name_len, &params) == FAILURE)
    {
        return;
    }
    swModule *module = swoole_get_object(getThis());
    if (module == NULL)
    {
        swoole_php_fatal_error(E_ERROR, "Please use swoole_load_module().");
        return;
    }
    swModule_function func = swHashMap_find(module->functions, name, name_len);
    if (func == NULL)
    {
        swoole_php_fatal_error(E_ERROR, "Module[%s] does not have [%s] function.", module->name, name);
        return;
    }

    swArgs_clear();
    zval *value;
    SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(params), value)
        switch(SW_Z_TYPE_P(value))
        {
        case IS_STRING:
            swParam_string(Z_STRVAL_P(value), Z_STRLEN_P(value));
            break;
        case IS_LONG:
            swParam_long(Z_LVAL_P(value));
            break;
        case IS_DOUBLE:
            swParam_double(Z_DVAL_P(value));
            break;
#if PHP_MAJOR_VERSION < 7
        case IS_BOOL:
            swParam_bool(Z_BVAL_P(value));
            break;
#else
        case IS_TRUE:
            swParam_bool(1);
            break;
        case IS_FALSE:
            swParam_bool(0);
            break;
#endif
        default:
            swWarn("unknown type.");
            RETURN_FALSE;
        }
    SW_HASHTABLE_FOREACH_END();

    swString *args = swString_dup2(SwooleG.call_php_func_args);
    if (args == NULL)
    {
        return;
    }
    swVal *retval = func(module, args, Z_ARRVAL_P(params)->nNumOfElements);
    if (swVal_to_zval(retval, return_value) < 0)
    {
        RETURN_NULL();
    }
    swString_free(args);
}