ACL_VSTREAM *local_listen() { const char *myname = "local_listen"; char lock_file[MAX_PATH], ebuf[256]; ACL_VSTREAM *sstream, *fp; ACL_FILE_HANDLE handle; get_lock_file(lock_file, sizeof(lock_file)); fp = acl_vstream_fopen(lock_file, O_RDWR | O_CREAT, 0600, 1024); if (fp == NULL) acl_msg_fatal("%s(%d): open file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); handle = ACL_VSTREAM_FILE(fp); if (acl_myflock(handle, 0, ACL_MYFLOCK_OP_EXCLUSIVE | ACL_MYFLOCK_OP_NOWAIT) == -1) { acl_msg_error("%s(%d): lock file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); return (NULL); } sstream = acl_vstream_listen_ex("127.0.0.1:0", 128, ACL_BLOCKING, 1024, 0); if (sstream == NULL) acl_msg_fatal("%s(%d): listen error(%s)", myname, __LINE__, acl_last_strerror(ebuf, sizeof(ebuf))); if (acl_file_ftruncate(fp, 0) < 0) acl_msg_fatal("%s(%d): truncate file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); if (acl_vstream_fseek(fp, 0, SEEK_SET) < 0) acl_msg_fatal("%s(%d): fseek file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); if (acl_vstream_fprintf(fp, "%s\r\n", sstream->local_addr) == ACL_VSTREAM_EOF) acl_msg_fatal("%s(%d): fprintf to file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); /* XXX: 只能采用先解排它锁,再加共享锁,微软比较弱!!! */ if (acl_myflock(handle, 0, ACL_MYFLOCK_OP_NONE) == -1) acl_msg_fatal("%s(%d): unlock file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); if (acl_myflock(handle, 0, ACL_MYFLOCK_OP_SHARED | ACL_MYFLOCK_OP_NOWAIT) == -1) acl_msg_fatal("%s(%d): lock file(%s) error(%s)", myname, __LINE__, lock_file, acl_last_strerror(ebuf, sizeof(ebuf))); return (sstream); }
SERVICE *service_create(const char *local_ip, short local_port, const char *dns_ip, short dns_port) { const char *myname = "service_create"; SERVICE *service; ACL_VSTREAM *sstream; char addr[64]; // 创建提供 TCP 方式查询时的监听流 snprintf(addr, sizeof(addr), "%s:%d", local_ip, local_port); sstream = acl_vstream_listen_ex(addr, 128, ACL_NON_BLOCKING, 1024, 10); if (sstream == NULL) { acl_msg_error("%s(%d): can't listen on addr(%s)", myname, __LINE__, addr); return (NULL); } service = (SERVICE*) acl_mycalloc(1, sizeof(SERVICE)); ACL_SAFE_STRNCPY(service->listen_addr, addr, sizeof(service->listen_addr)); ACL_SAFE_STRNCPY(service->dns_ip, dns_ip, sizeof(service->dns_ip)); service->dns_port = dns_port; snprintf(service->dns_addr, sizeof(service->dns_addr), "%s:%d", dns_ip, dns_port); service->conn_timeout = 10; service->rw_timeout = 10; service->table = acl_htable_create(100, 0); service->aio = acl_aio_create(ACL_EVENT_SELECT); service->sstream = acl_aio_open(service->aio, sstream); acl_aio_ctl(service->sstream, ACL_AIO_CTL_ACCEPT_FN, accept_callback, ACL_AIO_CTL_CTX, service, ACL_AIO_CTL_END); acl_aio_accept(service->sstream); service_udp_init(service, local_ip, local_port, dns_ip, dns_port); return (service); }
ACL_VSTREAM *acl_vstream_listen(const char *addr, int qlen) { return acl_vstream_listen_ex(addr, qlen, ACL_BLOCKING, 0, 0); }