/* Generated from "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod" by precompile.pike running Pike v8.0 release 1089
 *
 * Do NOT edit this file.
 */

#undef PRECOMPILE_API_VERSION
#define PRECOMPILE_API_VERSION 6

#undef PRECOMPILE_SUB_PIKEVARS
#define PRECOMPILE_SUB_PIKEVARS 1

#undef PRECOMPILE_DYNAMIC_TYPES
#define PRECOMPILE_DYNAMIC_TYPES 1



#undef cmod___CMOD__
#define cmod___CMOD__ 1
#line 1 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
#line 1 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
#line 1 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
#line 3003 "/Users/hww3/devel/pike/lib/modules/Tools.pmod/Standalone.pmod/precompile.pike"







#line 3010 "/Users/hww3/devel/pike/lib/modules/Tools.pmod/Standalone.pmod/precompile.pike"
#line 1 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
#line 1 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
/* -*- c -*-
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
*/

#include "global.h"
#include "stralloc.h"
#include "pike_macros.h"
#include "interpret.h"
#include "threads.h"
#include "program.h"
#include "program_id.h"
#include "object.h"
#include "operators.h"
#include "fdlib.h"
#include "fd_control.h"
#include "backend.h"
#include "module_support.h"
#include "array.h"
#include "builtin_functions.h"
#include "bignum.h"

#include "shuffler.h"
#include "sources.h"



#ifndef PIKE_UNUSED_ATTRIBUTE
#define PIKE_UNUSED_ATTRIBUTE
#endif
#define CMOD_MAP_PROGRAM_IDS_DEFINED 1
static int ___cmod_map_program_ids(int id) PIKE_UNUSED_ATTRIBUTE;
#ifndef TYPEOF
/* Compat with older Pikes. */
#define TYPEOF(SVAL)	((SVAL).type)
#define SUBTYPEOF(SVAL)	((SVAL).subtype)
#define SET_SVAL_TYPE(SVAL, TYPE)	(TYPEOF(SVAL) = TYPE)
#define SET_SVAL_SUBTYPE(SVAL, TYPE)	(SUBTYPEOF(SVAL) = TYPE)
#define SET_SVAL(SVAL, TYPE, SUBTYPE, FIELD, EXPR) do {	\
    /* Set the type afterwards to avoid a clobbered	\
     * svalue in case EXPR throws. */			\
    (SVAL).u.FIELD = (EXPR);				\
    SET_SVAL_TYPE((SVAL), (TYPE));			\
    SET_SVAL_SUBTYPE((SVAL), (SUBTYPE));		\
  } while(0)
#endif /* !TYPEOF */
#ifndef PIKE_UNUSED
/* Compat with Pike 7.8 and earlier. */
/* NB: Not strictly correct; PIKE_UNUSED was added the
 *     day after set_program_id_to_id(), but good enough.
 */
#ifndef UNUSED
#define UNUSED(X)	X
#endif
#ifndef set_program_id_to_id
/* NB: Recent Pike 7.8 has a #define that conflicts with
 *     the following declaration.
 */
static void set_program_id_to_id(void*UNUSED(id)){}
#endif
#else /* */
PMOD_EXPORT void set_program_id_to_id( int (*to)(int) );
#endif /* !PIKE_UNUSED */


#ifndef DEFAULT_CMOD_STORAGE
#define CMOD_COND_USED
#define DEFAULT_CMOD_STORAGE static
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_set_throttler_fun_num_used 1
#else
#undef f_Shuffle_set_throttler_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_sent_data_fun_num_used 1
#else
#undef f_Shuffle_sent_data_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_state_fun_num_used 1
#else
#undef f_Shuffle_state_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_create_fun_num_used 1
#else
#undef f_Shuffle_create_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_start_fun_num_used 1
#else
#undef f_Shuffle_start_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_pause_fun_num_used 1
#else
#undef f_Shuffle_pause_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_stop_fun_num_used 1
#else
#undef f_Shuffle_stop_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_add_source_fun_num_used 1
#else
#undef f_Shuffle_add_source_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define Shuffle_program_fun_num_used 1
#else
#undef Shuffle_program_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffler_set_backend_fun_num_used 1
#else
#undef f_Shuffler_set_backend_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffler_pause_fun_num_used 1
#else
#undef f_Shuffler_pause_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffler_start_fun_num_used 1
#else
#undef f_Shuffler_start_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffler_shuffle_fun_num_used 1
#else
#undef f_Shuffler_shuffle_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define Shuffler_program_fun_num_used 1
#else
#undef Shuffler_program_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_set_request_arg_fun_num_used 1
#else
#undef f_Shuffle_set_request_arg_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_set_done_callback_fun_num_used 1
#else
#undef f_Shuffle_set_done_callback_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffler_set_throttler_fun_num_used 1
#else
#undef f_Shuffler_set_throttler_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffler_cq____remove_shuffle_fun_num_used 1
#else
#undef f_Shuffler_cq____remove_shuffle_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_send_more_callback_fun_num_used 1
#else
#undef f_Shuffle_send_more_callback_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Shuffle_write_callback_fun_num_used 1
#else
#undef f_Shuffle_write_callback_fun_num_used
#endif
#line 29 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
#if 0
#include <stdio.h>
#define SHUFFLE_DEBUG1(fmt, arg1)			fprintf(stderr,"Shuffle[%p]:" fmt, arg1)
#define SHUFFLE_DEBUG2(fmt, arg1, arg2)			fprintf(stderr,"Shuffle[%p]:" fmt, arg1, arg2)
#define SHUFFLE_DEBUG3(fmt, arg1, arg2, arg3)		fprintf(stderr,"Shuffle[%p]:" fmt, arg1, arg2, arg3)
#define SHUFFLE_DEBUG4(fmt, arg1, arg2, arg3, arg4)	fprintf(stderr,"Shuffle[%p]:" fmt, arg1, arg2, arg3, arg4)
#else
#define SHUFFLE_DEBUG1(fmt, arg1)
#define SHUFFLE_DEBUG2(fmt, arg1, arg2)
#define SHUFFLE_DEBUG3(fmt, arg1, arg2, arg3)
#define SHUFFLE_DEBUG4(fmt, arg1, arg2, arg3, arg4)
#endif
#define BLOCK 8192
static void free_source( struct source *s )
{
debug_malloc_touch(s);
if( s->free_source ) s->free_source( s );
free( s );
}

DEFAULT_CMOD_STORAGE struct program *Shuffler_program;

/*! @module Shuffler
 *!
 *! Module implementing sending to and from nonblocking streams and other sources.
 *!
 *! Most useful when implementing sending of data from strings, files and
 *! other sources to a network connection. The module also supports
 *! generic bandwidth throttling.
 *!
 *! Multiple @[Shuffler] object can be created, each optionally with
 *! their own backend.
 *!
 *! This makes it easier to use more than one CPU for pure data
 *! transmission, just have multiple backends each in their own
 *! thread, with their own shuffle object.
 *!
 */

/*! @class Throttler
 *!
 *! @note
 *!  This is an interface that all @[Throttler]s must implement.
 *!  It's not an actual class in this module.
 *!
 *! @decl void request( Shuffle shuffle, int amount, function(int:void) callback )
 *! This function is called when the @[Shuffle] wants to send some
 *! data to a client.
 *!
 *! When data can be sent, the @[callback] function should be called
 *! with the amount of data that can be sent as the argument.
 *!
 *! @decl void give_back( Shuffle shuffle, int amount )
 *!
 *! This function will be called by the @[Shuffle] object to report
 *! that some data assigned to it by this throttler was unusued, and
 *! can be given to another @[Shuffle] object instead.
 */
/*! @endclass
 */

/*! @class Shuffle
 *! This class contains the state for one ongoing data
 *! shuffling operation. To create a @[Shuffle] instance, use the
 *! @[Shuffler()->shuffle] method.
 *!
 */


#undef class_Shuffle_defined
#define class_Shuffle_defined
DEFAULT_CMOD_STORAGE struct program *Shuffle_program=NULL;

#ifdef Shuffle_program_fun_num_used
DEFAULT_CMOD_STORAGE int Shuffle_program_fun_num=-1;
#endif /* Shuffle_program_fun_num_used */

#undef var_box_Shuffle_defined
#define var_box_Shuffle_defined

#undef var_shuffler_Shuffle_defined
#define var_shuffler_Shuffle_defined
/*! @decl Shuffler shuffler;
   *! The @[Shuffler] that owns this @[Shuffle] object
   *! 
  */

#undef var_throttler_Shuffle_defined
#define var_throttler_Shuffle_defined
/*! @decl Throttler throttler;
   *! The @[Throttler] that is associated with this @[Shuffle] object,
   *! if any.
   *! 
  */


#undef var_done_callback_Shuffle_defined
#define var_done_callback_Shuffle_defined

#undef var_request_arg_Shuffle_defined
#define var_request_arg_Shuffle_defined

#undef var_current_source_Shuffle_defined
#define var_current_source_Shuffle_defined

#undef var_last_source_Shuffle_defined
#define var_last_source_Shuffle_defined

#undef var_file_obj_Shuffle_defined
#define var_file_obj_Shuffle_defined

#undef var_callback_Shuffle_defined
#define var_callback_Shuffle_defined

#undef var_write_callback_Shuffle_defined
#define var_write_callback_Shuffle_defined

#undef var_sent_Shuffle_defined
#define var_sent_Shuffle_defined

#undef var_state_Shuffle_defined
#define var_state_Shuffle_defined

#undef var_leftovers_Shuffle_defined
#define var_leftovers_Shuffle_defined

#undef THIS
#define THIS ((struct Shuffle_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_SHUFFLE
#define THIS_SHUFFLE ((struct Shuffle_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_SHUFFLE
#define OBJ2_SHUFFLE(o) ((struct Shuffle_struct *)(o->storage+Shuffle_storage_offset))

#undef GET_SHUFFLE_STORAGE
#define GET_SHUFFLE_STORAGE(o) ((struct Shuffle_struct *)(o->storage+Shuffle_storage_offset)
static ptrdiff_t Shuffle_storage_offset;
struct Shuffle_struct {

#ifdef var_box_Shuffle_defined
#line 99 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct fd_callback_box box;
#endif /* var_box_Shuffle_defined */

#ifdef var_shuffler_Shuffle_defined
  struct object * shuffler;

#endif /* var_shuffler_Shuffle_defined */

#ifdef var_throttler_Shuffle_defined
  struct object * throttler;

#endif /* var_throttler_Shuffle_defined */

#ifdef var_done_callback_Shuffle_defined
  struct svalue done_callback;

#endif /* var_done_callback_Shuffle_defined */

#ifdef var_request_arg_Shuffle_defined
  struct svalue request_arg;

#endif /* var_request_arg_Shuffle_defined */

#ifdef var_current_source_Shuffle_defined
#line 117 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct source *current_source;
#endif /* var_current_source_Shuffle_defined */

#ifdef var_last_source_Shuffle_defined
#line 118 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct source *last_source;
#endif /* var_last_source_Shuffle_defined */

#ifdef var_file_obj_Shuffle_defined
#line 119 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct object *file_obj;
#endif /* var_file_obj_Shuffle_defined */

#ifdef var_callback_Shuffle_defined
#line 120 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
int callback;
#endif /* var_callback_Shuffle_defined */

#ifdef var_write_callback_Shuffle_defined
#line 121 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
int write_callback;
#endif /* var_write_callback_Shuffle_defined */

#ifdef var_sent_Shuffle_defined
#line 123 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
int sent;
#endif /* var_sent_Shuffle_defined */

#ifdef var_state_Shuffle_defined
#line 124 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
ShuffleState state;
#endif /* var_state_Shuffle_defined */

#ifdef var_leftovers_Shuffle_defined
#line 126 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct data leftovers;
#endif /* var_leftovers_Shuffle_defined */
};
#ifdef PIKE_DEBUG
/* Ensure the struct is used in a variable declaration, or else gdb might not see it. */
static struct Shuffle_struct *Shuffle_gdb_dummy_ptr;
#endif
#line 129 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
static void _send_more( struct Shuffle_struct *t );
static void __set_callbacks( struct Shuffle_struct *t )
{
SHUFFLE_DEBUG2("__set_calllbacks(%s)\n", t,(t->box.fd>0?"C":"Pike") );
if( t->box.fd >= 0 )
set_fd_callback_events(&t->box, PIKE_BIT_FD_WRITE, 0);
else if( t->file_obj && t->file_obj->prog )
{
ref_push_function( t->box.ref_obj, t->write_callback );
safe_apply( t->file_obj, "set_write_callback", 1 );
pop_stack();
}
else {
SHUFFLE_DEBUG1("EEP: No destination! Cannot set callbacks\n",t);
}
}

static void __remove_callbacks( struct Shuffle_struct *t )
{
SHUFFLE_DEBUG2("__remove_calllbacks(%s)\n", t, (t->box.fd>=0?"C":"Pike") );
if( t->box.fd >= 0 )
set_fd_callback_events(&t->box, 0, 0);
else if( t->file_obj && t->file_obj->prog )
{
push_int(0);
safe_apply( t->file_obj, "set_write_callback", 1 );
pop_stack();
}
else {
SHUFFLE_DEBUG1("EEP: No destination! Cannot remove callbacks\n",t);
}
}

static int got_shuffler_event(struct fd_callback_box*box, int DEBUGUSED(event)) {
#ifdef PIKE_DEBUG
 if (event != PIKE_FD_WRITE)
Pike_fatal ("Got unexpected event %d.\n", event);
#endif
 _send_more((struct Shuffle_struct*)
((char*)box-offsetof(struct Shuffle_struct,box)));

return 0; /* Everything OK. */
}

#define f_Shuffle_set_throttler_defined

#ifdef f_Shuffle_set_throttler_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_set_throttler_fun_num = 0;

#endif /* f_Shuffle_set_throttler_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_set_throttler(INT32 args) {
#line 173 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct object * t;
#line 173 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 1) wrong_number_of_args_error("set_throttler",args,1);
#line 173 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_OBJECT) SIMPLE_ARG_TYPE_ERROR("set_throttler",1,"object");
#line 173 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
debug_malloc_pass(t=Pike_sp[0-1].u.object);
/*! @decl void set_throttler(Throttler t)
   *! Calling this function overrides the @[Shuffler] global throttler.
   *! 
  */
#line 179 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
SHUFFLE_DEBUG2("set_throttler(%p)\n", THIS, t );
if( THIS->throttler )
free_object( THIS->throttler );
if( (THIS->throttler = t) ) {
debug_malloc_touch(THIS->throttler);
Pike_sp--;
}
else
pop_stack();
push_int(0);
}

}
#define f_Shuffle_sent_data_defined

#ifdef f_Shuffle_sent_data_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_sent_data_fun_num = 0;

#endif /* f_Shuffle_sent_data_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_sent_data(INT32 args) {
#line 192 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 0) wrong_number_of_args_error("sent_data",args,0);
/*! @decl int sent_data()
   *! Returns the amount of data that has been sent so far.
   *! 
  */
#line 198 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
SHUFFLE_DEBUG2("sent_data() --> %d\n", THIS, THIS->sent );
do { INT_TYPE ret_=(THIS->sent);  push_int(ret_); return; }while(0);
#line 201 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
}

}
#define f_Shuffle_state_defined

#ifdef f_Shuffle_state_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_state_fun_num = 0;

#endif /* f_Shuffle_state_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_state(INT32 args) {
#line 203 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 0) wrong_number_of_args_error("state",args,0);
/*! @decl int state()
   *! Returns the current state of the shuffler.
   *! This is one of the following:
   *!   @[INITIAL], 
   *!   @[RUNNING], 
   *!   @[PAUSED], 
   *!   @[DONE], 
   *!   @[WRITE_ERROR], 
   *!   @[READ_ERROR] and
   *!   @[USER_ABORT]
   *!   
  */
#line 217 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
SHUFFLE_DEBUG2("state() --> %d\n", THIS, THIS->state );
do { INT_TYPE ret_=(THIS->state);  push_int(ret_); return; }while(0);
#line 220 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
}

}

#undef internal_init_Shuffle_defined
#define internal_init_Shuffle_defined

#undef Shuffle_event_handler_defined
#define Shuffle_event_handler_defined
static void init_Shuffle_struct(void)
#line 223 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
THIS->leftovers.do_free = 0;
THIS->shuffler = 0;
THIS->throttler = 0;
THIS->sent = 0;
mark_free_svalue (&THIS->done_callback);
SET_SVAL(THIS->request_arg, PIKE_T_INT, NUMBER_NUMBER, integer, 0);
THIS->leftovers.len = 0;
THIS->current_source = NULL;
THIS->file_obj = NULL;
THIS->state = INITIAL;
THIS->callback = 
find_identifier("send_more_callback",Pike_fp->current_object->prog);

THIS->write_callback = 
find_identifier("write_callback",Pike_fp->current_object->prog);
INIT_FD_CALLBACK_BOX(&THIS->box, NULL, Pike_fp->current_object, -1,
0, got_shuffler_event, 0);
debug_malloc_touch(THIS->box.ref_obj);

SHUFFLE_DEBUG1("init()\n", THIS );
}


#undef Shuffle_gc_live_obj
#define Shuffle_gc_live_obj

#undef internal_exit_Shuffle_defined
#define internal_exit_Shuffle_defined

#undef Shuffle_event_handler_defined
#define Shuffle_event_handler_defined
static void exit_Shuffle_struct(void)
#line 247 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
SHUFFLE_DEBUG1("exit()\n", THIS );

if(THIS->box.fd >= 0) {
push_int( THIS->box.fd );
unhook_fd_callback_box(&THIS->box);
if(THIS->file_obj)
safe_apply( THIS->file_obj, "take_fd", 1 );
pop_stack();
}

if( THIS->file_obj )
{
free_object( THIS->file_obj );
THIS->file_obj = 0;
}
while( THIS->current_source )
{
struct source *n = THIS->current_source->next;
free_source( THIS->current_source );
THIS->current_source = n;
}

if( THIS->leftovers.data && THIS->leftovers.do_free )
{
debug_malloc_touch(THIS->leftovers.data);
free( THIS->leftovers.data );
THIS->leftovers.data = NULL;
THIS->leftovers.do_free = 0;
}
}

static void __send_more_callback( struct Shuffle_struct *t, int amount );
static void _request( struct Shuffle_struct *t, int amount )
{
SHUFFLE_DEBUG3("_request(%d) from %p\n", t, amount, t->throttler );
if( t->throttler && t->throttler->prog )
{
__remove_callbacks( t );
debug_malloc_touch( t->throttler );
debug_malloc_touch( t->box.ref_obj );
ref_push_object( t->box.ref_obj );
push_int( amount );
ref_push_function( t->box.ref_obj, t->callback );
push_svalue( &t->request_arg );
safe_apply( t->throttler, "request", 4 );
pop_stack();
}
else /* bypass the pike function calling for the case
  	* when no throttling is done 
  	*/
__send_more_callback( t, amount );
}

static void _send_more( struct Shuffle_struct *t )
{
int l = BLOCK;
SHUFFLE_DEBUG2("_send_more(%d)\n", t, t->box.fd );
if( t->leftovers.len > 0 )
l = t->leftovers.len;
_request( t, l );
}

static void _set_callbacks( struct Shuffle_struct *t )
{
SHUFFLE_DEBUG1("_set_callbacks()\n", t );
if( t->current_source && t->current_source->setup_callbacks )
t->current_source->setup_callbacks( t->current_source );
__set_callbacks( t );
}

static void _remove_callbacks( struct Shuffle_struct *t )
{
SHUFFLE_DEBUG1("_remove_callbacks()\n",t );
if( t->current_source && t->current_source->remove_callbacks )
t->current_source->remove_callbacks( t->current_source );
__remove_callbacks( t );
}

static void _all_done( struct Shuffle_struct *t, int reason )
{
SHUFFLE_DEBUG2("_all_done(%d)\n", t,reason );

/* We should set the reason for being done first of all */
switch( reason )
{
case 0: t->state = DONE; break;
case 1: t->state = WRITE_ERROR; break;
case 2: t->state = USER_ABORT; break;
case 3: t->state = READ_ERROR; break;
}

/* Remove our callbacks. */
_remove_callbacks( t );

if(t->box.fd >= 0) {
push_int( t->box.fd );
unhook_fd_callback_box(&t->box);
t->box.fd = -1;
if(t->file_obj)
safe_apply(t->file_obj, "take_fd", 1 );
pop_stack();
}

debug_malloc_touch( t->box.ref_obj );
ref_push_object( t->box.ref_obj );

/* It might have been destroyed. */
if( t->shuffler && t->shuffler->prog )
{
debug_malloc_touch( t->shuffler );
safe_apply( t->shuffler, "___remove_shuffle", 1 );
}
pop_stack();

/* Destroy file_obj if any. */
if( t->file_obj )
{
debug_malloc_touch( t->file_obj );
free_object( t->file_obj );
t->file_obj = 0;
}

/* Destroy all our sources. */
while( t->current_source )
{
struct source *n = t->current_source->next;
debug_malloc_touch( t->current_source );
free_source( t->current_source );
t->current_source = n;
}

/* Free any data left in pipe. */
if( t->leftovers.data && t->leftovers.do_free )
{
debug_malloc_touch( t->leftovers.data );
free( t->leftovers.data );
t->leftovers.data = NULL;
t->leftovers.do_free = 0;
}

t->leftovers.data = 0;

/* If a callback exists, we call it at the end, because done_callback might
     * explicitly destruct this object. This happened in one of the testcases.
     * Calling done_callback at the end essentially reverts commit
     * 95865471b36a441ad345cd7f23fe7d3260578c2f.
     *	/arne
     */
if( TYPEOF(t->done_callback) != PIKE_T_FREE )
{
SHUFFLE_DEBUG3("_all_done(%d): Calling done callback: %p\n", t,
reason, t->done_callback.u.object);
push_svalue( &t->done_callback );

/* Ensure us only calling the callback once. */
free_svalue(&t->done_callback);
mark_free_svalue(&t->done_callback);

ref_push_object( t->box.ref_obj );
push_int( reason );

apply_svalue( Pike_sp-3, 2 );
pop_stack();
pop_stack();
}
}

#define f_Shuffle_set_done_callback_defined

#ifdef f_Shuffle_set_done_callback_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_set_done_callback_fun_num = 0;

#endif /* f_Shuffle_set_done_callback_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_set_done_callback(INT32 args) {
#line 415 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct svalue * cb;
#line 415 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 1) wrong_number_of_args_error("set_done_callback",args,1);
#line 415 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
cb=Pike_sp+0-1; dmalloc_touch_svalue(Pike_sp+0-1);
/*! @decl void set_done_callback( function(Shuffle,int:void) cb )
    *! Sets the done callback. This function will be called when all
    *! sources have been processed, or if an error occurs.
    *! 
    */
#line 422 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
SHUFFLE_DEBUG2("set_done_callback(%p)\n", THIS, cb->u.object );
assign_svalue( &THIS->done_callback,cb);
if (TYPEOF(THIS->done_callback) == PIKE_T_INT)
mark_free_svalue (&THIS->done_callback);
}

}
#define f_Shuffle_set_request_arg_defined

#ifdef f_Shuffle_set_request_arg_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_set_request_arg_fun_num = 0;

#endif /* f_Shuffle_set_request_arg_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_set_request_arg(INT32 args) {
#line 429 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct svalue * arg;
#line 429 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 1) wrong_number_of_args_error("set_request_arg",args,1);
#line 429 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
arg=Pike_sp+0-1; dmalloc_touch_svalue(Pike_sp+0-1);
/*! @decl void set_request_arg( mixed arg )
    *!
    *! Sets the extra argument sent to @[Throttler()->request()] and
    *! @[Throttler()->give_back].
    *! 
    */
#line 437 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
SHUFFLE_DEBUG2("set_request_arg(%p)\n", THIS, arg->u.object );
assign_svalue( &THIS->request_arg, arg );
}

}
#line 442 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
static void _give_back( struct Shuffle_struct *t, int amount )
{
SHUFFLE_DEBUG2("_give_back(%d)\n", t, amount );
if( t->throttler && t->throttler->prog )
{
ref_push_object( t->box.ref_obj );
debug_malloc_touch( t->box.ref_obj );
debug_malloc_touch( t->throttler );
push_int( amount );
push_svalue( &t->request_arg );
safe_apply( t->throttler, "give_back", 3 );
pop_stack();
}
}

static void __send_more_callback( struct Shuffle_struct *t, int amount )
{
int sent = 0;
SHUFFLE_DEBUG2("__send_more_callback(%d)\n", t, amount );
while( t->leftovers.len < 1 )
{
while( t->current_source && t->current_source->eof )
{
struct source *n = t->current_source->next;
SHUFFLE_DEBUG2("__send_more_callback(): source done: %p\n", t, t->current_source );
if( t->current_source->remove_callbacks )
t->current_source->remove_callbacks( t->current_source );
free_source( t->current_source );
t->current_source = n;
if( n && n->setup_callbacks )
n->setup_callbacks( n );
}

if( !t->current_source )
{
SHUFFLE_DEBUG1("__send_more_callback(): no sources\n", t );
_give_back( t, amount );
_all_done( t, 0 );
return;
}

t->leftovers = t->current_source->get_data( t->current_source,
MAXIMUM(amount,8192) );

if( t->leftovers.len == -2 )
{
/* come back later (nonblocking source without more data to read) */
SHUFFLE_DEBUG1("__send_more_callback(): read pending\n", t );
__remove_callbacks( t );
t->current_source->set_callback( t->current_source,
(void *)_set_callbacks, t );
_give_back( t, amount );
return;
}
else if( t->leftovers.len < 0 )
{
SHUFFLE_DEBUG1("__send_more_callback(): read error\n", t );
/* read error */
_give_back( t, amount );
_all_done( t, 3 );
return;
}
}
/* Now it's time to actually send the data. */
SHUFFLE_DEBUG2("__send_more_callback(): sending(%d)\n", t,
MINIMUM(amount,t->leftovers.len));
sent = -1;
if( t->box.fd >= 0 )
{
THREADS_ALLOW();
sent = fd_write( t->box.fd, t->leftovers.data+t->leftovers.off,
MINIMUM(amount,t->leftovers.len) );
THREADS_DISALLOW();
}
else if( t->file_obj )
{
push_string( make_shared_binary_string(
t->leftovers.data+t->leftovers.off,
MINIMUM(amount,t->leftovers.len) ) );
apply( t->file_obj, "write", 1 );
if( TYPEOF(Pike_sp[-1]) == PIKE_T_INT )
sent = Pike_sp[-1].u.integer;
else
{
SHUFFLE_DEBUG2("Oops: write returned object of type %d, not integer\n",
t, TYPEOF(Pike_sp[-1]) );
}
pop_stack();
}
SHUFFLE_DEBUG3("__send_more_callback(): sending(%d): sent %d\n", t,
MINIMUM(t->leftovers.len,amount),sent );

if( sent < 0 )
{
_give_back( t, amount );
_all_done( t, 1 );
return;
}
if( sent )
{
t->sent += sent;
if( t->leftovers.len == sent )
{
t->leftovers.len = 0;
if( t->leftovers.do_free )
{
free( t->leftovers.data );
t->leftovers.data = NULL;
t->leftovers.do_free = 0;
}
}
else
{
t->leftovers.len -= sent;
t->leftovers.off += sent;
}
}
if( sent < amount )
_give_back( t, amount-sent );
}

/* internal use.. */
#define f_Shuffle_send_more_callback_defined

#ifdef f_Shuffle_send_more_callback_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_send_more_callback_fun_num = 0;

#endif /* f_Shuffle_send_more_callback_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_send_more_callback(INT32 args) {
#line 564 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
INT_TYPE amount;
#line 564 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 1) wrong_number_of_args_error("send_more_callback",args,1);
#line 564 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_INT) SIMPLE_ARG_TYPE_ERROR("send_more_callback",1,"int");
#line 564 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
amount=Pike_sp[0-1].u.integer;
#line 566 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
SHUFFLE_DEBUG2("send_more_callback(%d)\n", THIS,amount );
if( THIS->state == RUNNING )
{
__set_callbacks( THIS );
__send_more_callback( THIS, amount );
}
else
_give_back( THIS, amount );
}

}
#line 577 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
/* internal use.. */
#define f_Shuffle_write_callback_defined

#ifdef f_Shuffle_write_callback_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_write_callback_fun_num = 0;

#endif /* f_Shuffle_write_callback_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_write_callback(INT32 args) {
#line 578 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct svalue * x;
#line 578 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args > 1) wrong_number_of_args_error("write_callback",args,1);
#line 578 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if ((args > 0) &&
    ((TYPEOF(Pike_sp[0-args]) != PIKE_T_INT) ||
     (SUBTYPEOF(Pike_sp[0-args]) != NUMBER_UNDEFINED))) {
#line 578 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
x=Pike_sp+0-args; dmalloc_touch_svalue(Pike_sp+0-args);
#line 578 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
} else x = NULL;
#line 580 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
SHUFFLE_DEBUG1("write_callback()\n", THIS );
_send_more( THIS );
}

}
/*! @decl void create(object fd, object shuffler, mixed throttler,@
   *!                   mixed backend)
   *!
   *! This object is normally not created directly, instead use
   *! @[Shuffler()->shuffle]
   */
#define f_Shuffle_create_defined

#ifdef f_Shuffle_create_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_create_fun_num = 0;

#endif /* f_Shuffle_create_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_create(INT32 args) {
#line 591 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct object * fd;
struct object * shuffler;
struct svalue * throttler;
struct svalue * backend;
#line 591 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 4) wrong_number_of_args_error("create",args,4);
#line 591 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(TYPEOF(Pike_sp[0-4]) != PIKE_T_OBJECT) SIMPLE_ARG_TYPE_ERROR("create",1,"object");
#line 591 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
debug_malloc_pass(fd=Pike_sp[0-4].u.object);
if(TYPEOF(Pike_sp[1-4]) != PIKE_T_OBJECT) SIMPLE_ARG_TYPE_ERROR("create",2,"object");
#line 592 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
debug_malloc_pass(shuffler=Pike_sp[1-4].u.object);
throttler=Pike_sp+2-4; dmalloc_touch_svalue(Pike_sp+2-4);
backend=Pike_sp+3-4; dmalloc_touch_svalue(Pike_sp+3-4);
#line 596 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
struct Backend_struct *be = default_backend;

if( (args != 4) || !shuffler || !get_storage( shuffler, Shuffler_program ) )
Pike_error("This class cannot be instantiated directly\n");

THIS->file_obj = fd;
add_ref(THIS->file_obj);

THIS->shuffler = shuffler;
add_ref(THIS->shuffler);

if( TYPEOF(*throttler) == PIKE_T_OBJECT )
{
THIS->throttler = throttler->u.object;
add_ref(THIS->throttler);
}

if (find_identifier("release_fd", fd->prog) < 0)
change_fd_for_box(&THIS->box, -1);
else {
safe_apply( fd, "release_fd", 0 );
if(TYPEOF(*backend) == PIKE_T_OBJECT && backend->u.object) {
be = get_storage(backend->u.object, Backend_program);
if (!be) {
SIMPLE_BAD_ARG_ERROR("Shuffle->create()", 4,
"object(Pike.__Backend)");
}
}
change_fd_for_box(&THIS->box, Pike_sp[-1].u.integer);
pop_stack();
}

if( THIS->box.fd >= 0 )
{
set_nonblocking( THIS->box.fd, 1 );
if(THIS->box.backend) {
/* FIXME: Ought to change backend to be here. */
set_fd_callback_events(&THIS->box, 0, 0);
} else
INIT_FD_CALLBACK_BOX(&THIS->box, be, THIS->box.ref_obj,
THIS->box.fd, 0, got_shuffler_event, 0);
}
else
{
push_int( 0 ); /* read */
push_int( 0 ); /* write */
push_int( 0 ); /* close */
safe_apply( THIS->file_obj, "set_nonblocking", 3 );
pop_stack();
}

pop_n_elems( args );
push_int(0);
}

}
#define f_Shuffle_start_defined

#ifdef f_Shuffle_start_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_start_fun_num = 0;

#endif /* f_Shuffle_start_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_start(INT32 args) {
#line 652 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 0) wrong_number_of_args_error("start",args,0);
/*! @decl void start();
    *! Start sending data from the sources.
    *!
    */
#line 658 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
if( !THIS->file_obj )
Pike_error("Cannot start, no destination.\n");
THIS->state = RUNNING;
SHUFFLE_DEBUG1("start()\n", THIS );
_set_callbacks( THIS );
}

}
#define f_Shuffle_pause_defined

#ifdef f_Shuffle_pause_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_pause_fun_num = 0;

#endif /* f_Shuffle_pause_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_pause(INT32 args) {
#line 666 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 0) wrong_number_of_args_error("pause",args,0);
/*! @decl void pause();
    *! Temporarily pause all data transmission
    *!
    */
#line 672 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
THIS->state = PAUSED;
SHUFFLE_DEBUG1("pause()\n", THIS );
_remove_callbacks( THIS );
}

}
#define f_Shuffle_stop_defined

#ifdef f_Shuffle_stop_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_stop_fun_num = 0;

#endif /* f_Shuffle_stop_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_stop(INT32 args) {
#line 678 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 0) wrong_number_of_args_error("stop",args,0);
/*! @decl void stop();
    *! Stop all data transmission, and then call the done callback
    *!
    */
#line 684 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
SHUFFLE_DEBUG1("stop()\n", THIS );
_all_done( THIS, 2 );
}

}
#define f_Shuffle_add_source_defined

#ifdef f_Shuffle_add_source_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffle_add_source_fun_num = 0;

#endif /* f_Shuffle_add_source_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffle_add_source(INT32 args) {
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct svalue * source;
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct svalue * start;
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct svalue * length;
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args < 1) wrong_number_of_args_error("add_source",args,1);
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args > 3) wrong_number_of_args_error("add_source",args,3);
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
source=Pike_sp+0-args; dmalloc_touch_svalue(Pike_sp+0-args);
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if ((args > 1) &&
    ((TYPEOF(Pike_sp[1-args]) != PIKE_T_INT) ||
     (SUBTYPEOF(Pike_sp[1-args]) != NUMBER_UNDEFINED))) {
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
start=Pike_sp+1-args; dmalloc_touch_svalue(Pike_sp+1-args);
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
} else start = NULL;
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if ((args > 2) &&
    ((TYPEOF(Pike_sp[2-args]) != PIKE_T_INT) ||
     (SUBTYPEOF(Pike_sp[2-args]) != NUMBER_UNDEFINED))) {
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
length=Pike_sp+2-args; dmalloc_touch_svalue(Pike_sp+2-args);
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
} else length = NULL;
/*! @decl void add_source( mixed source, int|void start, int|void length );
    *! Add a new source to the list of data sources.
    *! The data from the sources will be sent in order.
    *!
    *! If start and length are not specified, the whole source will be
    *! sent, if start but not length is specified, the whole source,
    *! excluding the first @[start] bytes will be sent.
    *!
    *! Currently supported sources
    *! @dl
    *!   @item string
    *!     An ordinary 8-bit wide pike string.
    *!   @item System.Memory
    *!     An initialized instance of the System.Memory class.
    *!   @item Stdio.File
    *!     Stdio.File instance pointing to a normal file.
    *!   @item Stdio.Stream
    *!     Stdio.File instance pointing to a stream of some kind
    *!     (network socket, named pipe, stdin etc). Blocking or nonblocking.
    *!   @item Stdio.NonblockingStream|Stdio.Stream
    *!     An object implementing the callback based reading
    *!     (set_read_callback and set_close_callback).
    *! @enddl
    */
#line 715 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
INT64 rstart=0, rlength=-1;
struct source *res;

if( !THIS->file_obj )
Pike_error("Cannot add source, no destination.\n");

if( args > 1 )
{
if( TYPEOF(*start) == PIKE_T_OBJECT )
int64_from_bignum( &rstart, start->u.object );
else if( TYPEOF(*start) == PIKE_T_INT && !SUBTYPEOF(*start) )
rstart = start->u.integer;
}
if( args > 2 )
{
if( TYPEOF(*length) == PIKE_T_OBJECT )
int64_from_bignum( &rlength, length->u.object );
else if( TYPEOF(*length) == PIKE_T_INT && !SUBTYPEOF(*length) )
rlength = length->u.integer;
}
if( rlength == 0 )
{
pop_n_elems(args);
push_int(0);
return;
}
debug_malloc_touch( source );

res = source_make( source, rstart, rlength );

debug_malloc_touch( res );

SHUFFLE_DEBUG4("add_source(XX,%d,%d) --> %p\n", THIS,
(int)rstart, (int)rlength, res );
if( !res )
Pike_error("Failed to convert argument to a source\n");

res->next = NULL;
if( THIS->current_source )
{
THIS->last_source->next = res;
THIS->last_source = res;
}
else {
THIS->current_source = THIS->last_source = res;
}
pop_n_elems(args);
push_int(0);
}
}

#ifdef Shuffle_event_handler_defined
static void Shuffle_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_Shuffle_defined
  case PROG_EVENT_INIT: init_Shuffle_struct(); break;

#endif /* internal_init_Shuffle_defined */

#ifdef internal_exit_Shuffle_defined
  case PROG_EVENT_EXIT: exit_Shuffle_struct(); break;

#endif /* internal_exit_Shuffle_defined */
  default: break; 
  }
}

#endif /* Shuffle_event_handler_defined */
/*! @endclass
 */

/*! @class Shuffler
 *!
 *! A data shuffler. An instance of this class handles a list of
 *! @[Shuffle] objects. Each @[Shuffle] object can send data from one
 *! or more sources to a destination in the background.
 *! 
 */


#undef class_Shuffler_defined
#define class_Shuffler_defined
DEFAULT_CMOD_STORAGE struct program *Shuffler_program=NULL;

#ifdef Shuffler_program_fun_num_used
DEFAULT_CMOD_STORAGE int Shuffler_program_fun_num=-1;
#endif /* Shuffler_program_fun_num_used */

#undef var_backend_Shuffler_defined
#define var_backend_Shuffler_defined

#undef var_throttler_Shuffler_defined
#define var_throttler_Shuffler_defined

#undef var_paused_Shuffler_defined
#define var_paused_Shuffler_defined

#undef var_sources_Shuffler_defined
#define var_sources_Shuffler_defined

#undef THIS
#define THIS ((struct Shuffler_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef THIS_SHUFFLER
#define THIS_SHUFFLER ((struct Shuffler_struct *)(Pike_interpreter.frame_pointer->current_storage))

#undef OBJ2_SHUFFLER
#define OBJ2_SHUFFLER(o) ((struct Shuffler_struct *)(o->storage+Shuffler_storage_offset))

#undef GET_SHUFFLER_STORAGE
#define GET_SHUFFLER_STORAGE(o) ((struct Shuffler_struct *)(o->storage+Shuffler_storage_offset)
static ptrdiff_t Shuffler_storage_offset;
struct Shuffler_struct {

#ifdef var_backend_Shuffler_defined
  struct object * backend;

#endif /* var_backend_Shuffler_defined */

#ifdef var_throttler_Shuffler_defined
  struct object * throttler;

#endif /* var_throttler_Shuffler_defined */

#ifdef var_paused_Shuffler_defined
#line 783 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
int paused;
#endif /* var_paused_Shuffler_defined */

#ifdef var_sources_Shuffler_defined
  struct array * sources;

#endif /* var_sources_Shuffler_defined */
};
#ifdef PIKE_DEBUG
/* Ensure the struct is used in a variable declaration, or else gdb might not see it. */
static struct Shuffler_struct *Shuffler_gdb_dummy_ptr;
#endif
#line 787 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
static void update_sources(void)
{
push_array( THIS->sources );
debug_malloc_touch( THIS->sources );
push_int(0);
f_aggregate(1);
o_subtract();
THIS->sources = Pike_sp[-1].u.array;
debug_malloc_touch( THIS->sources );
Pike_sp--;
}


#define f_Shuffler_set_backend_defined

#ifdef f_Shuffler_set_backend_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffler_set_backend_fun_num = 0;

#endif /* f_Shuffler_set_backend_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffler_set_backend(INT32 args) {
#line 800 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct object * b;
#line 800 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 1) wrong_number_of_args_error("set_backend",args,1);
#line 800 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_OBJECT) SIMPLE_ARG_TYPE_ERROR("set_backend",1,"object");
#line 800 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
debug_malloc_pass(b=Pike_sp[0-1].u.object);
/*! @decl void set_backend( Pike.Backend b );
     *! Set the backend that will be used by all @[Shuffle] objects created
     *! from this shuffler.
     *! 
     */
{
if( THIS->backend )
free_object( THIS->backend );
THIS->backend = b;
debug_malloc_touch( THIS->backend );
Pike_sp--;
push_int(0);
}

}
#define f_Shuffler_set_throttler_defined

#ifdef f_Shuffler_set_throttler_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffler_set_throttler_fun_num = 0;

#endif /* f_Shuffler_set_throttler_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffler_set_throttler(INT32 args) {
#line 815 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct object * t;
#line 815 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args > 1) wrong_number_of_args_error("set_throttler",args,1);
#line 815 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if (args > 0 &&
    (TYPEOF(Pike_sp[0-args]) != PIKE_T_INT ||
     Pike_sp[0-args].u.integer)) {
#line 815 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(TYPEOF(Pike_sp[0-args]) != PIKE_T_OBJECT) SIMPLE_ARG_TYPE_ERROR("set_throttler",1,"object|void");
#line 815 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
debug_malloc_pass(t=Pike_sp[0-args].u.object);
#line 815 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
} else t = NULL;
/*! @decl void set_throttler( Throttler t );
     *! Set the throttler that will be used in all @[Shuffle] objects
     *! created from this shuffler, unless overridden in the
     *! @[Shuffle] objects.
     *! 
     */
{
if( THIS->throttler )
free_object( THIS->throttler );
debug_malloc_pass( THIS->throttler = t );
Pike_sp--;
push_int(0);
}

}
#define f_Shuffler_pause_defined

#ifdef f_Shuffler_pause_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffler_pause_fun_num = 0;

#endif /* f_Shuffler_pause_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffler_pause(INT32 args) {
#line 830 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 0) wrong_number_of_args_error("pause",args,0);
/*! @decl void pause();
     *! Pause all @[Shuffle] objects associated with this @[Shuffler]
     *! 
     */
{
int i;
update_sources();
for( i = 0; i<THIS->sources->size; i++ )
{
struct Shuffle_struct *s =
(struct Shuffle_struct *)THIS->sources->item[i].u.object->storage;
if( s->state == RUNNING )
_remove_callbacks( s );
}
}

}
#define f_Shuffler_start_defined

#ifdef f_Shuffler_start_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffler_start_fun_num = 0;

#endif /* f_Shuffler_start_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffler_start(INT32 args) {
#line 847 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 0) wrong_number_of_args_error("start",args,0);
/*! @decl void start();
     *! Unpause all @[Shuffle] objects associated with this @[Shuffler]
     *! 
     */
{
int i;
update_sources();
for( i = 0; i<THIS->sources->size; i++ )
{
struct Shuffle_struct *s =
(struct Shuffle_struct *)THIS->sources->item[i].u.object->storage;
if( s->state == RUNNING )
_set_callbacks( s );
}
}

}
#define f_Shuffler_cq____remove_shuffle_defined

#ifdef f_Shuffler_cq____remove_shuffle_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffler_cq____remove_shuffle_fun_num = 0;

#endif /* f_Shuffler_cq____remove_shuffle_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffler_cq____remove_shuffle(INT32 args) {
#line 864 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct object * so;
#line 864 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 1) wrong_number_of_args_error("___remove_shuffle",args,1);
#line 864 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_OBJECT) SIMPLE_ARG_TYPE_ERROR("___remove_shuffle",1,"object");
#line 864 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
debug_malloc_pass(so=Pike_sp[0-1].u.object);
{
f_aggregate(1);
push_array( THIS->sources );
stack_swap();
o_subtract();
THIS->sources = Pike_sp[-1].u.array;
debug_malloc_touch( THIS->sources );
Pike_sp--;
push_int(0);
}

}
#define f_Shuffler_shuffle_defined

#ifdef f_Shuffler_shuffle_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Shuffler_shuffle_fun_num = 0;

#endif /* f_Shuffler_shuffle_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Shuffler_shuffle(INT32 args) {
#line 876 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
struct object * destination;
#line 876 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(args != 1) wrong_number_of_args_error("shuffle",args,1);
#line 876 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_OBJECT) SIMPLE_ARG_TYPE_ERROR("shuffle",1,"object");
#line 876 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
debug_malloc_pass(destination=Pike_sp[0-1].u.object);
/*! @decl Shuffle shuffle( Stdio.NonblockingStream destination );
     *! Create a new @[Shuffle] object.
     *!
     *! The destination has to support nonblocking I/O.
     */
{
ref_push_object( Pike_fp->current_object ); /* shuffler */
if( THIS->throttler )
ref_push_object( THIS->throttler );
else
push_int( 0 );
if( THIS->backend )
ref_push_object( THIS->backend );
else
push_int( 0 );

push_object( clone_object( Shuffle_program, 4 ) );
stack_dup();
f_aggregate( 1 );
push_array( THIS->sources );
stack_swap();
f_add(2);
THIS->sources = Pike_sp[-1].u.array;
debug_malloc_touch( THIS->sources );
Pike_sp--;
}

}

#undef internal_init_Shuffler_defined
#define internal_init_Shuffler_defined

#undef Shuffler_event_handler_defined
#define Shuffler_event_handler_defined
static void init_Shuffler_struct(void)
#line 905 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
{
THIS->sources = allocate_array(0);
}

#ifdef Shuffler_event_handler_defined
static void Shuffler_event_handler(int ev) {
  switch(ev) {

#ifdef internal_init_Shuffler_defined
  case PROG_EVENT_INIT: init_Shuffler_struct(); break;

#endif /* internal_init_Shuffler_defined */
  default: break; 
  }
}

#endif /* Shuffler_event_handler_defined */
/*! @endclass
 */

/*! @decl constant INITIAL;
 *! @decl constant RUNNING;
 *! @decl constant PAUSED;
 *! @decl constant DONE;
 *! @decl constant WRITE_ERROR;
 *! @decl constant READ_ERROR;
 *! @decl constant USER_ABORT;
 *!  The state of an individual @[Shuffle] object.
 */

/*! @endmodule
 */

#line 926 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
PIKE_MODULE_INIT
{

#ifdef CMOD_MAP_PROGRAM_IDS_DEFINED
set_program_id_to_id( ___cmod_map_program_ids );

#endif /* CMOD_MAP_PROGRAM_IDS_DEFINED */

#ifdef class_Shuffle_defined

#ifdef PROG_SHUFFLE_ID
#line 97 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
  START_NEW_PROGRAM_ID(SHUFFLE);
#else
#line 97 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
  start_new_program();

#endif /* PROG_SHUFFLE_ID */
#line 97 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
  Shuffle_program = Pike_compiler->new_program;

#ifndef tObjImpl_SHUFFLE

#undef tObjIs_SHUFFLE
#define tObjIs_SHUFFLE "\3\1\177\0\0\2"

#undef tObjImpl_SHUFFLE
#define tObjImpl_SHUFFLE "\3\0\177\0\0\2"

#endif /* tObjImpl_SHUFFLE */

#ifdef THIS_SHUFFLE
  Shuffle_storage_offset = ADD_STORAGE(struct Shuffle_struct);
#endif /* THIS_SHUFFLE */

#ifdef var_shuffler_Shuffle_defined
  PIKE_MAP_VARIABLE("shuffler", Shuffle_storage_offset + OFFSETOF(Shuffle_struct, shuffler),
                    tObj, PIKE_T_OBJECT, 0);
#endif /* var_shuffler_Shuffle_defined */

#ifdef var_throttler_Shuffle_defined
  PIKE_MAP_VARIABLE("throttler", Shuffle_storage_offset + OFFSETOF(Shuffle_struct, throttler),
                    tObj, PIKE_T_OBJECT, 0);
#endif /* var_throttler_Shuffle_defined */

#ifdef var_done_callback_Shuffle_defined
  PIKE_MAP_VARIABLE("done_callback", Shuffle_storage_offset + OFFSETOF(Shuffle_struct, done_callback),
                    tMix, PIKE_T_MIXED, 0);
#endif /* var_done_callback_Shuffle_defined */

#ifdef var_request_arg_Shuffle_defined
  PIKE_MAP_VARIABLE("request_arg", Shuffle_storage_offset + OFFSETOF(Shuffle_struct, request_arg),
                    tMix, PIKE_T_MIXED, 0);
#endif /* var_request_arg_Shuffle_defined */

#ifdef Shuffle_event_handler_defined
  pike_set_prog_event_callback(Shuffle_event_handler);

#ifndef Shuffle_gc_live_obj
  Pike_compiler->new_program->flags &= ~PROGRAM_LIVE_OBJ;

#endif /* Shuffle_gc_live_obj */

#endif /* Shuffle_event_handler_defined */

#ifdef f_Shuffle_set_throttler_defined

#ifdef f_Shuffle_set_throttler_fun_num_used
  f_Shuffle_set_throttler_fun_num =
#endif /* f_Shuffle_set_throttler_fun_num_used */
#line 173 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("set_throttler", f_Shuffle_set_throttler, tFunc(tObj,tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Shuffle_set_throttler_defined */

#ifdef f_Shuffle_sent_data_defined

#ifdef f_Shuffle_sent_data_fun_num_used
  f_Shuffle_sent_data_fun_num =
#endif /* f_Shuffle_sent_data_fun_num_used */
#line 192 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("sent_data", f_Shuffle_sent_data, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Shuffle_sent_data_defined */

#ifdef f_Shuffle_state_defined

#ifdef f_Shuffle_state_fun_num_used
  f_Shuffle_state_fun_num =
#endif /* f_Shuffle_state_fun_num_used */
#line 203 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("state", f_Shuffle_state, tFunc(tNone,"\10\200\0\0\0\177\377\377\377"), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Shuffle_state_defined */

#ifdef f_Shuffle_set_done_callback_defined

#ifdef f_Shuffle_set_done_callback_fun_num_used
  f_Shuffle_set_done_callback_fun_num =
#endif /* f_Shuffle_set_done_callback_fun_num_used */
#line 415 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("set_done_callback", f_Shuffle_set_done_callback, tFunc(tMix,tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Shuffle_set_done_callback_defined */

#ifdef f_Shuffle_set_request_arg_defined

#ifdef f_Shuffle_set_request_arg_fun_num_used
  f_Shuffle_set_request_arg_fun_num =
#endif /* f_Shuffle_set_request_arg_fun_num_used */
#line 429 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("set_request_arg", f_Shuffle_set_request_arg, tFunc(tMix,tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Shuffle_set_request_arg_defined */

#ifdef f_Shuffle_send_more_callback_defined

#ifdef f_Shuffle_send_more_callback_fun_num_used
  f_Shuffle_send_more_callback_fun_num =
#endif /* f_Shuffle_send_more_callback_fun_num_used */
#line 564 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("send_more_callback", f_Shuffle_send_more_callback, tFunc("\10\200\0\0\0\177\377\377\377",tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Shuffle_send_more_callback_defined */

#ifdef f_Shuffle_write_callback_defined

#ifdef f_Shuffle_write_callback_fun_num_used
  f_Shuffle_write_callback_fun_num =
#endif /* f_Shuffle_write_callback_fun_num_used */
#line 578 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("write_callback", f_Shuffle_write_callback, tFunc(tOr(tMix,tVoid),tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Shuffle_write_callback_defined */

#ifdef f_Shuffle_create_defined

#ifdef f_Shuffle_create_fun_num_used
  f_Shuffle_create_fun_num =
#endif /* f_Shuffle_create_fun_num_used */
#line 591 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("create", f_Shuffle_create, tFunc(tObj tObj tMix tMix,tVoid), ID_PROTECTED, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Shuffle_create_defined */

#ifdef f_Shuffle_start_defined

#ifdef f_Shuffle_start_fun_num_used
  f_Shuffle_start_fun_num =
#endif /* f_Shuffle_start_fun_num_used */
#line 652 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("start", f_Shuffle_start, tFunc(tNone,tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Shuffle_start_defined */

#ifdef f_Shuffle_pause_defined

#ifdef f_Shuffle_pause_fun_num_used
  f_Shuffle_pause_fun_num =
#endif /* f_Shuffle_pause_fun_num_used */
#line 666 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("pause", f_Shuffle_pause, tFunc(tNone,tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Shuffle_pause_defined */

#ifdef f_Shuffle_stop_defined

#ifdef f_Shuffle_stop_fun_num_used
  f_Shuffle_stop_fun_num =
#endif /* f_Shuffle_stop_fun_num_used */
#line 678 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("stop", f_Shuffle_stop, tFunc(tNone,tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Shuffle_stop_defined */

#ifdef f_Shuffle_add_source_defined

#ifdef f_Shuffle_add_source_fun_num_used
  f_Shuffle_add_source_fun_num =
#endif /* f_Shuffle_add_source_fun_num_used */
#line 689 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("add_source", f_Shuffle_add_source, tFunc(tMix tOr(tMix,tVoid) tOr(tMix,tVoid),tVoid), 0, OPT_SIDE_EFFECT);

#endif /* f_Shuffle_add_source_defined */
#line 97 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
  Shuffle_program=end_program();
#line 97 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
#ifdef Shuffle_program_fun_num_used
Shuffle_program_fun_num=
#endif
 add_program_constant("Shuffle",Shuffle_program,0);

#endif /* class_Shuffle_defined */

#ifdef class_Shuffler_defined

#ifdef PROG_SHUFFLER_ID
#line 778 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
  START_NEW_PROGRAM_ID(SHUFFLER);
#else
#line 778 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
  start_new_program();

#endif /* PROG_SHUFFLER_ID */
#line 778 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
  Shuffler_program = Pike_compiler->new_program;

#ifndef tObjImpl_SHUFFLER

#undef tObjIs_SHUFFLER
#define tObjIs_SHUFFLER "\3\1\177\0\0\3"

#undef tObjImpl_SHUFFLER
#define tObjImpl_SHUFFLER "\3\0\177\0\0\3"

#endif /* tObjImpl_SHUFFLER */

#ifdef THIS_SHUFFLER
  Shuffler_storage_offset = ADD_STORAGE(struct Shuffler_struct);
#endif /* THIS_SHUFFLER */

#ifdef var_backend_Shuffler_defined
  PIKE_MAP_VARIABLE("backend", Shuffler_storage_offset + OFFSETOF(Shuffler_struct, backend),
                    tObj, PIKE_T_OBJECT, 0);
#endif /* var_backend_Shuffler_defined */

#ifdef var_throttler_Shuffler_defined
  PIKE_MAP_VARIABLE("throttler", Shuffler_storage_offset + OFFSETOF(Shuffler_struct, throttler),
                    tObj, PIKE_T_OBJECT, 0);
#endif /* var_throttler_Shuffler_defined */

#ifdef var_sources_Shuffler_defined
  PIKE_MAP_VARIABLE("sources", Shuffler_storage_offset + OFFSETOF(Shuffler_struct, sources),
                    tArray, PIKE_T_ARRAY, 0);
#endif /* var_sources_Shuffler_defined */

#ifdef Shuffler_event_handler_defined
  pike_set_prog_event_callback(Shuffler_event_handler);

#ifndef Shuffler_gc_live_obj
  Pike_compiler->new_program->flags &= ~PROGRAM_LIVE_OBJ;

#endif /* Shuffler_gc_live_obj */

#endif /* Shuffler_event_handler_defined */

#ifdef f_Shuffler_set_backend_defined

#ifdef f_Shuffler_set_backend_fun_num_used
  f_Shuffler_set_backend_fun_num =
#endif /* f_Shuffler_set_backend_fun_num_used */
#line 800 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("set_backend", f_Shuffler_set_backend, tFunc(tObj,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Shuffler_set_backend_defined */

#ifdef f_Shuffler_set_throttler_defined

#ifdef f_Shuffler_set_throttler_fun_num_used
  f_Shuffler_set_throttler_fun_num =
#endif /* f_Shuffler_set_throttler_fun_num_used */
#line 815 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("set_throttler", f_Shuffler_set_throttler, tFunc(tOr(tObj,tVoid),tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Shuffler_set_throttler_defined */

#ifdef f_Shuffler_pause_defined

#ifdef f_Shuffler_pause_fun_num_used
  f_Shuffler_pause_fun_num =
#endif /* f_Shuffler_pause_fun_num_used */
#line 830 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("pause", f_Shuffler_pause, tFunc(tNone,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Shuffler_pause_defined */

#ifdef f_Shuffler_start_defined

#ifdef f_Shuffler_start_fun_num_used
  f_Shuffler_start_fun_num =
#endif /* f_Shuffler_start_fun_num_used */
#line 847 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("start", f_Shuffler_start, tFunc(tNone,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Shuffler_start_defined */

#ifdef f_Shuffler_cq____remove_shuffle_defined

#ifdef f_Shuffler_cq____remove_shuffle_fun_num_used
  f_Shuffler_cq____remove_shuffle_fun_num =
#endif /* f_Shuffler_cq____remove_shuffle_fun_num_used */
#line 864 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("___remove_shuffle", f_Shuffler_cq____remove_shuffle, tFunc(tObj,tVoid), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Shuffler_cq____remove_shuffle_defined */

#ifdef f_Shuffler_shuffle_defined

#ifdef f_Shuffler_shuffle_fun_num_used
  f_Shuffler_shuffle_fun_num =
#endif /* f_Shuffler_shuffle_fun_num_used */
#line 876 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    ADD_FUNCTION2("shuffle", f_Shuffler_shuffle, tFunc(tObj,tObj), 0, OPT_EXTERNAL_DEPEND|OPT_SIDE_EFFECT);

#endif /* f_Shuffler_shuffle_defined */
#line 778 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
  Shuffler_program=end_program();
#line 778 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
#ifdef Shuffler_program_fun_num_used
Shuffler_program_fun_num=
#endif
 add_program_constant("Shuffler",Shuffler_program,0);

#endif /* class_Shuffler_defined */

#ifdef CMOD_MAP_PROGRAM_IDS_DEFINED
set_program_id_to_id( 0 );
#endif /* CMOD_MAP_PROGRAM_IDS_DEFINED */
#line 928 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
;
sources_init();
add_integer_constant( "INITIAL", INITIAL, 0 );
add_integer_constant( "RUNNING", RUNNING, 0 );
add_integer_constant( "PAUSED", PAUSED, 0 );
add_integer_constant( "DONE", DONE, 0 );
add_integer_constant( "WRITE_ERROR", WRITE_ERROR, 0 );
add_integer_constant( "READ_ERROR", READ_ERROR, 0 );
add_integer_constant( "USER_ABORT", USER_ABORT, 0 );
}

PIKE_MODULE_EXIT
{

#ifdef class_Shuffle_defined
  if(Shuffle_program) {
#line 97 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    free_program(Shuffle_program);
    Shuffle_program=0;
  }

#endif /* class_Shuffle_defined */

#ifdef class_Shuffler_defined
  if(Shuffler_program) {
#line 778 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
    free_program(Shuffler_program);
    Shuffler_program=0;
  }

#endif /* class_Shuffler_defined */
#line 941 "/Users/hww3/devel/pike/src/post_modules/Shuffler/Shuffler.cmod"
;
sources_exit();
}


#ifdef CMOD_MAP_PROGRAM_IDS_DEFINED
static int ___cmod_map_program_ids(int id)
{
  int i = 0;
  if( (id&0x7f000000) != 0x7f000000 ) return id;
  id = id&0x00ffffff;
#ifdef class_Shuffle_defined
if(id==2) return Shuffle_program->id;
#endif
#ifdef class_Shuffler_defined
if(id==3) return Shuffler_program->id;
#endif
  return 0;
}
#endif /* CMOD_MAP_PROGRAM_IDS_DEFINED */
