Browse Source

remove unused code (mostly intended for ASICs which are not supported in sgminer), fix some compiler warnings

djm34
Jan Berdajs 11 years ago
parent
commit
5e3142cf68
  1. 2
      algorithm/scrypt.c
  2. 25
      miner.h
  3. 422
      sgminer.c
  4. 4
      util.c

2
algorithm/scrypt.c

@ -418,5 +418,3 @@ void scrypt_regenhash(struct work *work)
scrypt_n_1_1_256_sp(data, scratchbuf, ohash, work->pool->algorithm.n); scrypt_n_1_1_256_sp(data, scratchbuf, ohash, work->pool->algorithm.n);
flip32(ohash, ohash); flip32(ohash, ohash);
} }
static const uint32_t diff1targ = 0x0000ffff;

25
miner.h

@ -522,11 +522,6 @@ struct cgpu_info {
struct sgminer_stats sgminer_stats; struct sgminer_stats sgminer_stats;
pthread_rwlock_t qlock;
struct work *queued_work;
struct work *unqueued_work;
unsigned int queued_count;
bool shutdown; bool shutdown;
struct timeval dev_start_tv; struct timeval dev_start_tv;
@ -1009,7 +1004,6 @@ extern pthread_cond_t restart_cond;
extern void clear_stratum_shares(struct pool *pool); extern void clear_stratum_shares(struct pool *pool);
extern void clear_pool_work(struct pool *pool); extern void clear_pool_work(struct pool *pool);
extern void set_target(unsigned char *dest_target, double diff, double diff_multiplier2); extern void set_target(unsigned char *dest_target, double diff, double diff_multiplier2);
extern int restart_wait(struct thr_info *thr, unsigned int mstime);
extern void kill_work(void); extern void kill_work(void);
@ -1061,7 +1055,6 @@ extern struct cgpu_info gpus[MAX_GPUDEVICES];
extern double total_secs; extern double total_secs;
extern int mining_threads; extern int mining_threads;
extern int total_devices; extern int total_devices;
extern int zombie_devs;
extern struct cgpu_info **devices; extern struct cgpu_info **devices;
extern int total_pools; extern int total_pools;
extern struct pool **pools; extern struct pool **pools;
@ -1368,26 +1361,9 @@ struct work {
extern void get_datestamp(char *, size_t, struct timeval *); extern void get_datestamp(char *, size_t, struct timeval *);
extern void inc_hw_errors(struct thr_info *thr); extern void inc_hw_errors(struct thr_info *thr);
extern bool test_nonce(struct work *work, uint32_t nonce); extern bool test_nonce(struct work *work, uint32_t nonce);
extern bool test_nonce_diff(struct work *work, uint32_t nonce, double diff);
extern bool submit_tested_work(struct thr_info *thr, struct work *work); extern bool submit_tested_work(struct thr_info *thr, struct work *work);
extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce); extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
extern bool submit_noffset_nonce(struct thr_info *thr, struct work *work, uint32_t nonce,
int noffset);
extern struct work *get_work(struct thr_info *thr, const int thr_id); extern struct work *get_work(struct thr_info *thr, const int thr_id);
extern void __add_queued(struct cgpu_info *cgpu, struct work *work);
extern struct work *get_queued(struct cgpu_info *cgpu);
extern void add_queued(struct cgpu_info *cgpu, struct work *work);
extern struct work *get_queue_work(struct thr_info *thr, struct cgpu_info *cgpu, int thr_id);
extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
extern struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
extern void __work_completed(struct cgpu_info *cgpu, struct work *work);
extern int age_queued_work(struct cgpu_info *cgpu, double secs);
extern void work_completed(struct cgpu_info *cgpu, struct work *work);
extern struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
extern void flush_queue(struct cgpu_info *cgpu);
extern void hash_driver_work(struct thr_info *mythr);
extern void hash_queued_work(struct thr_info *mythr);
extern void _wlog(const char *str); extern void _wlog(const char *str);
extern void _wlogprint(const char *str); extern void _wlogprint(const char *str);
extern int curses_int(const char *query); extern int curses_int(const char *query);
@ -1416,7 +1392,6 @@ extern void adl(void);
extern void app_restart(void); extern void app_restart(void);
extern void clean_work(struct work *work); extern void clean_work(struct work *work);
extern void free_work(struct work *work); extern void free_work(struct work *work);
extern void set_work_ntime(struct work *work, int ntime);
extern struct work *copy_work_noffset(struct work *base_work, int noffset); extern struct work *copy_work_noffset(struct work *base_work, int noffset);
#define copy_work(work_in) copy_work_noffset(work_in, 0) #define copy_work(work_in) copy_work_noffset(work_in, 0)
extern struct thr_info *get_thread(int thr_id); extern struct thr_info *get_thread(int thr_id);

422
sgminer.c

@ -100,7 +100,6 @@ int opt_expiry = 28;
algorithm_t *opt_algorithm; algorithm_t *opt_algorithm;
static const bool opt_time = true;
unsigned long long global_hashrate; unsigned long long global_hashrate;
unsigned long global_quota_gcd = 1; unsigned long global_quota_gcd = 1;
bool opt_show_coindiff = false; bool opt_show_coindiff = false;
@ -117,7 +116,6 @@ static int opt_devs_enabled;
static bool opt_display_devs; static bool opt_display_devs;
static bool opt_removedisabled; static bool opt_removedisabled;
int total_devices; int total_devices;
int zombie_devs;
static int most_devices; static int most_devices;
struct cgpu_info **devices; struct cgpu_info **devices;
int mining_threads; int mining_threads;
@ -816,6 +814,7 @@ static char *set_pool_thread_concurrency(const char *arg)
return NULL; return NULL;
} }
#ifdef HAVE_ADL
static char *set_pool_gpu_engine(const char *arg) static char *set_pool_gpu_engine(const char *arg)
{ {
struct pool *pool = get_current_pool(); struct pool *pool = get_current_pool();
@ -843,6 +842,7 @@ static char *set_pool_gpu_fan(const char *arg)
pool->gpu_fan = arg; pool->gpu_fan = arg;
return NULL; return NULL;
} }
#endif
static char *set_pool_nfactor(const char *arg) static char *set_pool_nfactor(const char *arg)
{ {
@ -3736,17 +3736,6 @@ static void _copy_work(struct work *work, const struct work *base_work, int noff
work->coinbase = strdup(base_work->coinbase); work->coinbase = strdup(base_work->coinbase);
} }
void set_work_ntime(struct work *work, int ntime)
{
uint32_t *work_ntime = (uint32_t *)(work->data + 68);
*work_ntime = htobe32(ntime);
if (work->ntime) {
free(work->ntime);
work->ntime = bin2hex((unsigned char *)work_ntime, 4);
}
}
/* Generates a copy of an existing work struct, creating fresh heap allocations /* Generates a copy of an existing work struct, creating fresh heap allocations
* for all dynamically allocated arrays within the struct. noffset is used for * for all dynamically allocated arrays within the struct. noffset is used for
* when a driver has internally rolled the ntime, noffset is a relative value. * when a driver has internally rolled the ntime, noffset is a relative value.
@ -4035,34 +4024,6 @@ static void discard_stale(void)
applog(LOG_DEBUG, "Discarded %d stales that didn't match current hash", stale); applog(LOG_DEBUG, "Discarded %d stales that didn't match current hash", stale);
} }
/* A generic wait function for threads that poll that will wait a specified
* time tdiff waiting on the pthread conditional that is broadcast when a
* work restart is required. Returns the value of pthread_cond_timedwait
* which is zero if the condition was met or ETIMEDOUT if not.
*/
int restart_wait(struct thr_info *thr, unsigned int mstime)
{
struct timeval now, then, tdiff;
struct timespec abstime;
int rc;
tdiff.tv_sec = mstime / 1000;
tdiff.tv_usec = mstime * 1000 - (tdiff.tv_sec * 1000000);
cgtime(&now);
timeradd(&now, &tdiff, &then);
abstime.tv_sec = then.tv_sec;
abstime.tv_nsec = then.tv_usec * 1000;
mutex_lock(&restart_lock);
if (thr->work_restart)
rc = 0;
else
rc = pthread_cond_timedwait(&restart_cond, &restart_lock, &abstime);
mutex_unlock(&restart_lock);
return rc;
}
static void *restart_thread(void __maybe_unused *arg) static void *restart_thread(void __maybe_unused *arg)
{ {
struct pool *cp = current_pool(); struct pool *cp = current_pool();
@ -4089,7 +4050,6 @@ static void *restart_thread(void __maybe_unused *arg)
if (cgpu->deven != DEV_ENABLED) if (cgpu->deven != DEV_ENABLED)
continue; continue;
mining_thr[i]->work_restart = true; mining_thr[i]->work_restart = true;
flush_queue(cgpu);
cgpu->drv->flush_work(cgpu); cgpu->drv->flush_work(cgpu);
} }
@ -4157,17 +4117,6 @@ static bool block_exists(char *hexstr)
return false; return false;
} }
/* Tests if this work is from a block that has been seen before */
static inline bool from_existing_block(struct work *work)
{
char *hexstr = bin2hex(work->data + 8, 18);
bool ret;
ret = block_exists(hexstr);
free(hexstr);
return ret;
}
static int block_sort(struct block *blocka, struct block *blockb) static int block_sort(struct block *blocka, struct block *blockb)
{ {
return blocka->block_no - blockb->block_no; return blocka->block_no - blockb->block_no;
@ -4475,7 +4424,10 @@ void write_config(FILE *fcfg)
if (nDevs) { if (nDevs) {
fputs(",\n\"intensity\" : \"", fcfg); fputs(",\n\"intensity\" : \"", fcfg);
for(i = 0; i < nDevs; i++) for(i = 0; i < nDevs; i++)
fprintf(fcfg, gpus[i].dynamic ? "%sd" : "%s%d", i > 0 ? "," : "", gpus[i].intensity); if (gpus[i].dynamic)
fprintf(fcfg, "%sd", i > 0 ? "," : "");
else
fprintf(fcfg, "%s%d", i > 0 ? "," : "", gpus[i].intensity);
fputs("\",\n\"xintensity\" : \"", fcfg); fputs("\",\n\"xintensity\" : \"", fcfg);
for(i = 0; i < nDevs; i++) for(i = 0; i < nDevs; i++)
@ -6288,7 +6240,7 @@ static void get_work_prepare_thread(struct thr_info *mythr, struct work *work)
n_threads = mining_threads; n_threads = mining_threads;
#endif #endif
if (unlikely(pthread_create(&restart_thr, NULL, restart_mining_threads_thread, (void *)n_threads))) if (unlikely(pthread_create(&restart_thr, NULL, restart_mining_threads_thread, (void *) (intptr_t) n_threads)))
quit(1, "restart_mining_threads create thread failed"); quit(1, "restart_mining_threads create thread failed");
sleep(60); sleep(60);
quit(1, "thread was not cancelled in 60 seconds after restart_mining_threads"); quit(1, "thread was not cancelled in 60 seconds after restart_mining_threads");
@ -6422,18 +6374,6 @@ bool test_nonce(struct work *work, uint32_t nonce)
return (le32toh(*hash_32) <= diff1targ); return (le32toh(*hash_32) <= diff1targ);
} }
/* For testing a nonce against an arbitrary diff */
bool test_nonce_diff(struct work *work, uint32_t nonce, double diff)
{
uint64_t *hash64 = (uint64_t *)(work->hash + 24), diff64;
rebuild_nonce(work, nonce);
diff64 = work->pool->algorithm.diff_nonce;
diff64 /= diff;
return (le64toh(*hash64) <= diff64);
}
static void update_work_stats(struct thr_info *thr, struct work *work) static void update_work_stats(struct thr_info *thr, struct work *work)
{ {
double test_diff = current_diff; double test_diff = current_diff;
@ -6489,36 +6429,6 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
return true; return true;
} }
/* Allows drivers to submit work items where the driver has changed the ntime
* value by noffset. Must be only used with a work protocol that does not ntime
* roll itself intrinsically to generate work (eg stratum). We do not touch
* the original work struct, but the copy of it only. */
bool submit_noffset_nonce(struct thr_info *thr, struct work *work_in, uint32_t nonce,
int noffset)
{
struct work *work = make_work();
bool ret = false;
_copy_work(work, work_in, noffset);
if (!test_nonce(work, nonce)) {
inc_hw_errors(thr);
goto out;
}
ret = true;
update_work_stats(thr, work);
if (!fulltest(work->hash, work->target)) {
applog(LOG_INFO, "%s %d: Share above target", thr->cgpu->drv->name,
thr->cgpu->device_id);
goto out;
}
submit_work_async(work);
out:
if (!ret)
free_work(work);
return ret;
}
static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes) static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes)
{ {
if (wdiff->tv_sec > opt_scantime || if (wdiff->tv_sec > opt_scantime ||
@ -6708,315 +6618,6 @@ static void hash_sole_work(struct thr_info *mythr)
cgpu->deven = DEV_DISABLED; cgpu->deven = DEV_DISABLED;
} }
/* Put a new unqueued work item in cgpu->unqueued_work under cgpu->qlock till
* the driver tells us it's full so that it may extract the work item using
* the get_queued() function which adds it to the hashtable on
* cgpu->queued_work. */
static void fill_queue(struct thr_info *mythr, struct cgpu_info *cgpu, struct device_drv *drv, const int thr_id)
{
do {
bool need_work;
/* Do this lockless just to know if we need more unqueued work. */
need_work = (!cgpu->unqueued_work);
/* get_work is a blocking function so do it outside of lock
* to prevent deadlocks with other locks. */
if (need_work) {
struct work *work = get_work(mythr, thr_id);
wr_lock(&cgpu->qlock);
/* Check we haven't grabbed work somehow between
* checking and picking up the lock. */
if (likely(!cgpu->unqueued_work))
cgpu->unqueued_work = work;
else
need_work = false;
wr_unlock(&cgpu->qlock);
if (unlikely(!need_work))
discard_work(work);
}
/* The queue_full function should be used by the driver to
* actually place work items on the physical device if it
* does have a queue. */
} while (!drv->queue_full(cgpu));
}
/* Add a work item to a cgpu's queued hashlist */
void __add_queued(struct cgpu_info *cgpu, struct work *work)
{
cgpu->queued_count++;
HASH_ADD_INT(cgpu->queued_work, id, work);
}
/* This function is for retrieving one work item from the unqueued pointer and
* adding it to the hashtable of queued work. Code using this function must be
* able to handle NULL as a return which implies there is no work available. */
struct work *get_queued(struct cgpu_info *cgpu)
{
struct work *work = NULL;
wr_lock(&cgpu->qlock);
if (cgpu->unqueued_work) {
work = cgpu->unqueued_work;
if (unlikely(stale_work(work, false))) {
discard_work(work);
work = NULL;
wake_gws();
} else
__add_queued(cgpu, work);
cgpu->unqueued_work = NULL;
}
wr_unlock(&cgpu->qlock);
return work;
}
void add_queued(struct cgpu_info *cgpu, struct work *work)
{
wr_lock(&cgpu->qlock);
__add_queued(cgpu, work);
wr_unlock(&cgpu->qlock);
}
/* Get fresh work and add it to cgpu's queued hashlist */
struct work *get_queue_work(struct thr_info *thr, struct cgpu_info *cgpu, int thr_id)
{
struct work *work = get_work(thr, thr_id);
add_queued(cgpu, work);
return work;
}
/* This function is for finding an already queued work item in the
* given que hashtable. Code using this function must be able
* to handle NULL as a return which implies there is no matching work.
* The calling function must lock access to the que if it is required.
* The common values for midstatelen, offset, datalen are 32, 64, 12 */
struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)
{
struct work *work, *tmp, *ret = NULL;
HASH_ITER(hh, que, work, tmp) {
if (memcmp(work->midstate, midstate, midstatelen) == 0 &&
memcmp(work->data + offset, data, datalen) == 0) {
ret = work;
break;
}
}
return ret;
}
/* This function is for finding an already queued work item in the
* device's queued_work hashtable. Code using this function must be able
* to handle NULL as a return which implies there is no matching work.
* The common values for midstatelen, offset, datalen are 32, 64, 12 */
struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)
{
struct work *ret;
rd_lock(&cgpu->qlock);
ret = __find_work_bymidstate(cgpu->queued_work, midstate, midstatelen, data, offset, datalen);
rd_unlock(&cgpu->qlock);
return ret;
}
struct work *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)
{
struct work *work, *ret = NULL;
rd_lock(&cgpu->qlock);
work = __find_work_bymidstate(cgpu->queued_work, midstate, midstatelen, data, offset, datalen);
if (work)
ret = copy_work(work);
rd_unlock(&cgpu->qlock);
return ret;
}
void __work_completed(struct cgpu_info *cgpu, struct work *work)
{
cgpu->queued_count--;
HASH_DEL(cgpu->queued_work, work);
}
/* This iterates over a queued hashlist finding work started more than secs
* seconds ago and discards the work as completed. The driver must set the
* work->tv_work_start value appropriately. Returns the number of items aged. */
int age_queued_work(struct cgpu_info *cgpu, double secs)
{
struct work *work, *tmp;
struct timeval tv_now;
int aged = 0;
cgtime(&tv_now);
wr_lock(&cgpu->qlock);
HASH_ITER(hh, cgpu->queued_work, work, tmp) {
if (tdiff(&tv_now, &work->tv_work_start) > secs) {
__work_completed(cgpu, work);
aged++;
}
}
wr_unlock(&cgpu->qlock);
return aged;
}
/* This function should be used by queued device drivers when they're sure
* the work struct is no longer in use. */
void work_completed(struct cgpu_info *cgpu, struct work *work)
{
wr_lock(&cgpu->qlock);
__work_completed(cgpu, work);
wr_unlock(&cgpu->qlock);
free_work(work);
}
/* Combines find_queued_work_bymidstate and work_completed in one function
* withOUT destroying the work so the driver must free it. */
struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen)
{
struct work *work;
wr_lock(&cgpu->qlock);
work = __find_work_bymidstate(cgpu->queued_work, midstate, midstatelen, data, offset, datalen);
if (work)
__work_completed(cgpu, work);
wr_unlock(&cgpu->qlock);
return work;
}
void flush_queue(struct cgpu_info *cgpu)
{
struct work *work = NULL;
if (unlikely(!cgpu))
return;
/* Use only a trylock in case we get into a deadlock with a queueing
* function holding the read lock when we're called. */
if (wr_trylock(&cgpu->qlock))
return;
work = cgpu->unqueued_work;
cgpu->unqueued_work = NULL;
wr_unlock(&cgpu->qlock);
if (work) {
free_work(work);
applog(LOG_DEBUG, "Discarded queued work item");
}
}
/* This version of hash work is for devices that are fast enough to always
* perform a full nonce range and need a queue to maintain the device busy.
* Work creation and destruction is not done from within this function
* directly. */
void hash_queued_work(struct thr_info *mythr)
{
struct timeval tv_start = {0, 0}, tv_end;
struct cgpu_info *cgpu = mythr->cgpu;
struct device_drv *drv = cgpu->drv;
const int thr_id = mythr->id;
int64_t hashes_done = 0;
while (likely(!cgpu->shutdown)) {
struct timeval diff;
int64_t hashes;
mythr->work_update = false;
fill_queue(mythr, cgpu, drv, thr_id);
hashes = drv->scanwork(mythr);
/* Reset the bool here in case the driver looks for it
* synchronously in the scanwork loop. */
mythr->work_restart = false;
if (unlikely(hashes == -1 )) {
applog(LOG_ERR, "%s %d failure, disabling!", drv->name, cgpu->device_id);
cgpu->deven = DEV_DISABLED;
dev_error(cgpu, REASON_THREAD_ZERO_HASH);
break;
}
hashes_done += hashes;
cgtime(&tv_end);
timersub(&tv_end, &tv_start, &diff);
/* Update the hashmeter at most 5 times per second */
if ((hashes_done && (diff.tv_sec > 0 || diff.tv_usec > 200000)) ||
diff.tv_sec >= opt_log_interval) {
hashmeter(thr_id, &diff, hashes_done);
hashes_done = 0;
copy_time(&tv_start, &tv_end);
}
if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED))
mt_disable(mythr, thr_id, drv);
if (mythr->work_update)
drv->update_work(cgpu);
}
cgpu->deven = DEV_DISABLED;
}
/* This version of hash_work is for devices drivers that want to do their own
* work management entirely, usually by using get_work(). Note that get_work
* is a blocking function and will wait indefinitely if no work is available
* so this must be taken into consideration in the driver. */
void hash_driver_work(struct thr_info *mythr)
{
struct timeval tv_start = {0, 0}, tv_end;
struct cgpu_info *cgpu = mythr->cgpu;
struct device_drv *drv = cgpu->drv;
const int thr_id = mythr->id;
int64_t hashes_done = 0;
while (likely(!cgpu->shutdown)) {
struct timeval diff;
int64_t hashes;
mythr->work_update = false;
hashes = drv->scanwork(mythr);
/* Reset the bool here in case the driver looks for it
* synchronously in the scanwork loop. */
mythr->work_restart = false;
if (unlikely(hashes == -1 )) {
applog(LOG_ERR, "%s %d failure, disabling!", drv->name, cgpu->device_id);
cgpu->deven = DEV_DISABLED;
dev_error(cgpu, REASON_THREAD_ZERO_HASH);
break;
}
hashes_done += hashes;
cgtime(&tv_end);
timersub(&tv_end, &tv_start, &diff);
/* Update the hashmeter at most 5 times per second */
if ((hashes_done && (diff.tv_sec > 0 || diff.tv_usec > 200000)) ||
diff.tv_sec >= opt_log_interval) {
hashmeter(thr_id, &diff, hashes_done);
hashes_done = 0;
copy_time(&tv_start, &tv_end);
}
if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED))
mt_disable(mythr, thr_id, drv);
if (mythr->work_update)
drv->update_work(cgpu);
}
cgpu->deven = DEV_DISABLED;
}
void *miner_thread(void *userdata) void *miner_thread(void *userdata)
{ {
struct thr_info *mythr = (struct thr_info *)userdata; struct thr_info *mythr = (struct thr_info *)userdata;
@ -8055,9 +7656,6 @@ void enable_device(struct cgpu_info *cgpu)
#ifdef HAVE_CURSES #ifdef HAVE_CURSES
adj_width(mining_threads, &dev_width); adj_width(mining_threads, &dev_width);
#endif #endif
rwlock_init(&cgpu->qlock);
cgpu->queued_work = NULL;
} }
struct _cgpu_devid_counter { struct _cgpu_devid_counter {
@ -8068,8 +7666,8 @@ struct _cgpu_devid_counter {
static void adjust_mostdevs(void) static void adjust_mostdevs(void)
{ {
if (total_devices - zombie_devs > most_devices) if (total_devices > most_devices)
most_devices = total_devices - zombie_devs; most_devices = total_devices;
} }
bool add_cgpu(struct cgpu_info *cgpu) bool add_cgpu(struct cgpu_info *cgpu)
@ -8202,7 +7800,7 @@ static void restart_mining_threads(unsigned int new_n_threads)
static void *restart_mining_threads_thread(void *userdata) static void *restart_mining_threads_thread(void *userdata)
{ {
restart_mining_threads((unsigned int) userdata); restart_mining_threads((unsigned int) (intptr_t) userdata);
return NULL; return NULL;
} }

4
util.c

@ -52,8 +52,10 @@ bool successful_connect = false;
static void keep_sockalive(SOCKETTYPE fd) static void keep_sockalive(SOCKETTYPE fd)
{ {
const int tcp_one = 1; const int tcp_one = 1;
#ifdef __linux
const int tcp_keepidle = 45;
#endif
#ifndef WIN32 #ifndef WIN32
const int tcp_keepidle = 45;
const int tcp_keepintvl = 30; const int tcp_keepintvl = 30;
int flags = fcntl(fd, F_GETFL, 0); int flags = fcntl(fd, F_GETFL, 0);

Loading…
Cancel
Save