/* transfer K items from the old hash table to the new one. */ static void dict_rehash(struct dict *d) { long k = DICT_REHASH_BATCH_SIZE; struct bucket *b, *next; if(d->ht_old == NULL) { return; } /* transfer old elements to the new HT. */ for(b = d->ht_old->first; b && k--;) { struct bucket *b_new; unsigned long h = d->key_hash(b->k, b->sz); if((b_new = ht_insert(d->ht, h, b->k, b->sz, b->v))) { /* new used slot, add to list. */ ht_record_used_bucket(d->ht, b_new); } next = b->next; /* re-attach b's neighbours together and free b. */ bucket_free(b); b = next; } if((d->ht_old->first = b)) { return; } ht_free(d->ht_old, d->key_free); d->ht_old = NULL; }
static void bucket_shutdown_handler(evutil_socket_t fd, short what, void *arg) { bucket_t *bucket = arg; int done = 0; assert(fd == -1); assert(arg); assert(bucket); assert(bucket->shutdown_event); // if the bucket is a backup bucket, we can simply destroy it, and send out a message to clients // that it is no longer the backup for the bucket. if (bucket->level > 0) { done ++; } else { assert(bucket->level == 0); // if the bucket is primary, but there are no nodes to send it to, then we destroy it. if (node_active_count() == 0) { done ++; } else { // If the backup node is connected, then we will tell that node, that it has been // promoted to be primary for the bucket. if (bucket->backup_node) { assert(bucket->backup_node->client); push_promote(bucket->backup_node->client, bucket->hashmask); assert(bucket->promoting == NOT_PROMOTING); bucket->promoting = PROMOTING; done ++; } else { // at this point, we are the primary and there is no backup. There are other nodes // connected, so we need to try and transfer this bucket to another node. assert(0); assert(done == 0); // assert(_buckets[i]->transfer_event == NULL); // _buckets[i]->transfer_event = evtimer_new(_evbase, bucket_transfer_handler, _buckets[i]); // assert(_buckets[i]->transfer_event); } } } if (done > 0) { // we are done with the bucket. assert(bucket->transfer_client == NULL); bucket_destroy_contents(bucket); update_hashmasks(bucket); assert(bucket->shutdown_event); event_free(bucket->shutdown_event); bucket->shutdown_event = NULL; assert(_buckets[bucket->hashmask] == bucket); _buckets[bucket->hashmask] = NULL; bucket_free(bucket); bucket = NULL; } else { // we are not done yet, so we need to schedule the event again. assert(bucket->shutdown_event); evtimer_add(bucket->shutdown_event, &_timeout_shutdown); } }
static int _impl_setup(rh_aout_api_itf self) { extern AAssetManager * __rh_hack_get_android_asset_manager(); static const SLEngineOption options[] = { { SL_ENGINEOPTION_THREADSAFE, SL_BOOLEAN_TRUE }, { SL_ENGINEOPTION_LOSSOFCONTROL, SL_BOOLEAN_FALSE }, }; struct sles_api_instance * instance = (struct sles_api_instance *)self; instance->asset_manager = __rh_hack_get_android_asset_manager(); if(!instance->asset_manager) goto bad; if (SL_RESULT_SUCCESS != slCreateEngine(&instance->engineObject, sizeof(options) / sizeof(options[0]), options, 0, NULL, NULL)) goto bad; if (SL_RESULT_SUCCESS != (*instance->engineObject)->Realize(instance->engineObject, SL_BOOLEAN_FALSE )) goto bad; if (SL_RESULT_SUCCESS != (*instance->engineObject)->GetInterface(instance->engineObject, SL_IID_ENGINE, &instance->engineItf)) goto bad; if (SL_RESULT_SUCCESS != (*instance->engineItf)->CreateOutputMix(instance->engineItf, &instance->outputMix, 0, NULL, NULL)) goto bad; if (SL_RESULT_SUCCESS != (*instance->outputMix)->Realize(instance->outputMix, SL_BOOLEAN_FALSE )) goto bad; if( pipe( &instance->cmd_pipe.read ) != 0 ) goto bad; if(fcntl( instance->cmd_pipe.read, F_SETFL, O_NONBLOCK) != 0) goto bad; if(bucket_create(&instance->aout_itf_bucket) != 0) goto bad; if(add_channels(self, 3) != 0) goto bad; { pthread_t thread; if(pthread_create(&thread, NULL, &api_main_loop, (void*)self) != 0) goto bad; instance->thread = thread; } pthread_detach( instance->thread ); good: return 0; bad: if( instance->outputMix ) (*instance->outputMix)->Destroy(instance->outputMix); if( instance->engineObject ) (*instance->engineObject)->Destroy(instance->engineObject); if(instance->aout_itf_bucket) { close_all_channels(self); bucket_free(instance->aout_itf_bucket); } if(instance->cmd_pipe.write) close(instance->cmd_pipe.write); if(instance->cmd_pipe.read) close(instance->cmd_pipe.read); return -1; }