Abstract:
A method that uses a single callback function for a multiphase service with possible discontinuation of execution between the phases. The method is based on assignment of a case in the callback function for each phase or state of the service and a stack of state descriptors. At each call to the callback function, the top descriptor is popped off the stack and the appropriate case in the callback function is run.

Description:
FIELD OF THE INVENTION  
         [0001]    The present invention relates generally to software engineering, and specifically to methods of program control.  
         BACKGROUND OF THE INVENTION  
         [0002]    It is a common occurrence in computer system applications that a program thread must call a service provided by the system. For example, a program thread in a data migration and backup application typically needs to make multiple calls to read/write services on the source and target disks for the application. When the thread calls the service, it typically receives a response indicating whether or not the service is prepared to handle the call. Such a response might be “proceed” if the service completed sucessfully, “wait” if the service is busy handling other requests, or “error” in the case of a fault.  
           [0003]    The program thread must be prepared to handle these different sorts of responses in the appropriate way. Continuing with the preceding example, the program thread should respond to “proceed” by continuing the program flow corresponding to a successful completion of the service. When “wait” is returned, the program thread should typically continue with other activities if possible, and then return to request the service again after a certain time has elapsed. Alternatively, the service notifies the program thread subsequently when it has completed the requested steps. In the case of “error,” the thread should report the problem to the user or take other corrective action as appropriate.  
           [0004]    The accepted way of handling these multiple cases is to define a separate callback function for handling each phase or state of the service, with each callback returning a code such as “proceed,” “wait” or “error.” This approach is conceptually straightforward, but in complex system applications, it leads to correspondingly complex program structures, with many different types of callbacks. This proliferation of non-uniform callback functions creates difficulties in writing and debugging the application software.  
         SUMMARY OF THE INVENTION  
         [0005]    In preferred embodiments of the present invention, a single callback function is provided for use by a program thread in invoking a system service. The callback function contains multiple cases, each corresponding to a different state of the service. The service state is typically indicated by a return code that is returned by the service when it is invoked. The callback function uses a stack of case values to keep track of the state of the service. Whenever the function is called, it pops the most recent value from the stack in order to determine the current state of the service and, accordingly, to select the appropriate case to run using a case switch. In the course of running the selected case, the function typically pushes a new case value onto the stack, in order to indicate the next case to be selected.  
           [0006]    The multi-case callback function structure of the present invention thus provides a uniform framework for all callbacks connected with a given service, eliminating the need to write a separate callback function for each possible state of the service or system. This framework can be used to create callback functions for substantially all of the system services that are to be invoked by an application, enabling the application to be structured and programmed in an orderly and transparent manner. Applications that are programmed in this manner are also easy to debug, by using a trace file of the interactions of the callback function with the pointer stack to follow the program flow in runtime.  
           [0007]    There is therefore provided, in accordance with a preferred embodiment of the present invention, a method for invoking a service on a host processor in a computer-controlled system, including:  
           [0008]    providing a single callback function having multiple cases, each such case corresponding to a state of the service;  
           [0009]    creating a stack in a memory of the host processor, the stack containing one or more state descriptors indicative of the state of the service;  
           [0010]    calling the function on the host processor in order to invoke the service;  
           [0011]    responsive to calling the function, popping one of the state descriptors from the stack so as to determine the state of the service; and  
           [0012]    running the case in the callback function that corresponds to the determined state.  
           [0013]    Preferably, running the case includes pushing a further one of the descriptors onto the stack for use in determining the case in the single callback function that is to be run next. More preferably, calling the function includes requesting access to a resource of the system, and running the case includes running code so as to-access the resource. Further preferably, running the case includes returning a code indicative of an outcome of the access. Most preferably, to branch from one case to another, a next one of the descriptors is popped from the stack and the case that corresponds to the next popped descriptor is run.  
           [0014]    Preferably, calling the function includes calling a wrapper function when the service is invoked by a process thread, and the wrapper function pushes a first one of the descriptors onto the stack to be popped by the single callback function.  
           [0015]    There is also provided, in accordance with a preferred embodiment of the present invention, computing apparatus, including:  
           [0016]    a memory, arranged to store a stack containing one of more state descriptors indicative of a state of a service in a computer-controlled system; and  
           [0017]    a host processor, which is arranged to invoke the service by calling a single callback function having multiple cases corresponding to the state of the service, such that responsive to calling the function, the processor pops one of the descriptors is popped from the stack so as to determine the state of the service, and runs the case in the callback function that corresponds to the determined state.  
           [0018]    There is additionally provided, in accordance with a preferred embodiment of the present invention, a computer software product, comprising a computer-readable medium in which program instructions are stored, the instructions comprising a single callback function having multiple cases, each such case corresponding to a state of a service in a computer-controlled system, which instructions, when read by a computer, cause the computer to store a stack containing one of more state descriptors indicative of the state of the service, to invoke the service by calling the callback function, such that responsive to calling the function, one of the descriptors is popped from the stack so as to determine the state of the service, and to run the case in the callback function that corresponds to the determined state.  
           [0019]    The present invention will be more fully understood from the following detailed description of the preferred embodiments thereof, taken together with the drawings in which: 
       
    
    
     BRIEF DESCRIPTION OF THE DRAWINGS  
       [0020]    [0020]FIG. 1 is a block diagram that schematically illustrates a computer system in which a callback function is used to invoke a system service, in accordance with a preferred embodiment of the present invention;  
         [0021]    [0021]FIG. 2 is a block diagram that schematically illustrates data structures in a computer memory that are used by a callback function, in accordance with a preferred embodiment of the present invention; and  
         [0022]    [0022]FIG. 3 is a flow chart that schematically illustrates a method for invoking a system service using a callback function, in accordance with a preferred embodiment of the present invention.  
     
    
     DETAILED DESCRIPTION OF PREFERRED EMBODIMENTS  
       [0023]    [0023]FIG. 1 is a schematic diagram of computer system  10 , in accordance with a preferred embodiment of the present invention. System  10  comprises one or more central processing units  12  (CPUs) which is programmed to carry out various functions, some of which are described below. The CPUs utilize a memory unit  14  for temporary storage of data and commands. Throughout the processing of the various functions, it becomes necessary to access scarce system resources. For example, CPUs  12  can read and write across an input/output (I/O) bus  16  to a long-term storage resource  18 . Typically, only one process at a time can read and write across I/O bus  16 , and the speed of access to storage resource  18  is much slower than the speed of the CPUs. Additionally, each request for a system resource access comprises many steps. Writing to a storage resource, for example, comprises obtaining exclusive access to the resource, sending the information to be written to the resource, checking that no errors occurred, and releasing the exclusive access. One of the steps may not succeed, because of a system failure or because the resource is busy handling other requests.  
         [0024]    A method of scheduling use of the system resources must take into account that many fast processes running in different threads or on different CPUs  12  in a SMP (symmetric multiprocessor) system may simultaneously request the same system resource. A scheduling process in system  10 , henceforth referred to as a service, receives and handles requests from a process thread running on CPUs  12  to access system resources, such as storage resource  18 . An example of such a service is a copy service, used to make copies of data in storage resource  18 . The service also coordinates the steps involved in properly accessing the resource, and informs the process threads of any problems. The service is implemented by suitable software running on system  10 , possibly in cooperation with other systems. The software may be supplied to the appropriate systems in electronic form, by downloading over a network, for example, or it may alternatively be supplied on tangible media, such as CD-ROM or non-volatile memory.  
         [0025]    [0025]FIG. 2 is a block diagram that schematically illustrates data structures in memory  14  used by the service, in accordance with a preferred embodiment of the present invention. In response to service requests from process threads on CPUs  12 , the service invokes a callback function  20 . The callback function comprises procedures for each of a plurality of cases  21 , corresponding to different possible steps in completing system resource  18  access such as:  
         [0026]    allocating space for structures in memory,  
         [0027]    locking access to the system resource,  
         [0028]    writing to the system resource,  
         [0029]    unlocking access to the system resource,  
         [0030]    checking for write errors,  
         [0031]    freeing the allocated memory.  
         [0032]    Execution of each case can result in one of a plurality of results. In the present example, the possible results are as follows:  
         [0033]    Proceed result—The requested step in the access of system resource  18  was completed as requested.  
         [0034]    Wait result—The requested step in the access of system resource  18  could not be completed, but was queued for execution.  
         [0035]    Error result—The requested step was rejected.  
         [0036]    Callback function  20  utilizes a Task Control Block (TCB)  22 , comprising a last-in-first-out (LIFO) stack  24 . Each element of stack  24  comprises a state value  26 . State value  26  indicates to the callback function which particular stage of the system resource access is next to execute, and thus tells the callback function which of cases  21  to invoke. TCB  22  is a structure that comprises additional information necessary to complete each stage of the system resource access. In the present example, TCB  22  comprises the device number of the storage resource to be accessed, the length of the user data to be written to the resource, and a pointer to the user data. The first element of stack  24  is given the subscript I. Subsequent elements are counted backwards, with consecutive subscripts I- 1 , I- 2  until the final element I-N, wherein N+1 is the number of elements, or length, of stack  24 . Pushing an element onto the stack refers to adding it to the stack at position I. Popping an element from the stack refers to removing the element at the top of the stack (initially position I)..  
         [0037]    Reference is now made to FIG. 3, which schematically illustrates invocation of a service, such as the copy service described above, using callback function  20 , in accordance with a preferred embodiment of the present invention. Reference is also made to a C language source code listing in an Appendix to this application, which illustrates an exemplary callback function used in the copy service and a wrapper function used to set up the first stage in the resource access. Line numbers mentioned in the description below refer to lines in the code listing. The goal of the copy service is to copy data from location to another. Requests to copy the data, each comprising a command to access system resources, are queued for processing since the time required to write the data to the new location is much longer than the time required to register the request. The queue is implemented in the example as a path of chained requests. Each request is chained to a subsequent request, and the entire chain forms a path through the different requests. A process thread on CPUs  12  calls the copy service, at a service call step  30  in FIG. 3 (corresponding to calling wrapper function csEstablishPaths at line  17  in the code listing). At an initialization step  32  (lines  32  to  47 ), the wrapper function fills information into TCB  22 , which is necessary to enable the service to complete the system resource access. In the example of storage resource  18 , the TCB comprises information on the destination label of the storage device, whether to read or to write data, the size of the data chunk to read/write, and a sequence number of the chunk of data to be read or written relative to other data. The wrapper function verifies the correctness of the data, then pushes the first state value  26  onto the stack at line  49 .  
         [0038]    The wrapper function calls the callback function at a calling step  34  (line  50 ). The callback function initializes its data structures, then pops an element from the stack at a stack pop step  36  (line  117 ).  
         [0039]    At function switch step  38 , value  26  of the popped element is used as the case in a case switch (line  128 ). The case switch directs the callback function to the proper case  21  for that value. The different cases are enumerated in lines  129 - 237  of the code. The cases executed responsive to state values  26  correspond to the following steps in the copy process:  
         [0040]    Case CONTROL_STEP — 1 and CONTROL_STEP — 2: filling fields in the TCBs at lines  129  and  136 ,  
         [0041]    Case CONTROL_STEP — 3: linking the TCBs at line  145  and calling the logical path establishment service,  
         [0042]    Case CONTROL_STEP — 4: checking for an error in the establishment of the logical paths on which chains will be executed at line  206 ,  
         [0043]    Case CONTROL_STEP — 5: finalizing TCBs and data for the next step at line  220 ,  
         [0044]    Case CONTROL_STEP — 6: hardening of the path data at line  227 , and  
         [0045]    Case CONTROL_STEP — 7: TCBs waiting for completion of the current thread at line  237 .  
         [0046]    As each case is handled, callback function  20  takes appropriate action, depending on the current case, at an action step  40 . Each case&#39;s action step completes a different step in the total process of accessing the system resource, as enumerated above. A further value  26  corresponding to the case to be selected in the following stage in the system resource access process is pushed onto the stack at a stack push step  42 . Alternatively, as exemplified in the code at lines  130  and  131 , the order of action step  40  and stack push step  42  may be reversed. Action step  40  returns a code indicating the success of the system operation at a code return step  44 . In the exemplary embodiment represented by the Appendix, three possible codes are returned. The resource may be unavailable, in which case the callback function returns a wait response to the service at a return wait response step  46  (line  295  in the callback function and line  63  of the wrapper function).  
         [0047]    Alternatively, the system may return a success code. In this case, the callback function checks whether the system resource access is complete at a done test step  48 . While the task is not done, the callback function pops the next value  26  from the stack at stack pop step  36  (line  256 ) and continues with switch step  38  (line  128 ). If the task is done, the callback function returns a done response to the service at return done state step  52 , after first cleaning up the chain of TCB pointers (lines  273  to  289 ). The callback function then returns a done response directly to the calling thread at a return step  54 , utilizing a function pointer located on a global stack (lines  290 - 292 ). The function calling the callback function pushes its function pointer onto the global stack prior to calling the callback function. An example of such a push operation is shown in the wrapper function (line  47 ). The global stack enables the callback function (and through it the service) to return control to the calling function even though the functions may execute in different threads.  
         [0048]    Further alternatively, code return step  44  may return an error code. The callback function checks whether it can recover from the error at a recovery test step  56  (line  208 ). If the callback function can recover from the error, it reports the error at an error reporting step  58  (line  212 ). The callback function then continues as if the system had returned a success code, at done test step  48 . If the callback cannot recover from the error, it cleans up the TCB pointer chain at a return error response step  62 , and the callback function then returns an error response directly to the calling thread at return step  54 . In this case, there is no need to push a next case onto the stack.  
         [0049]    When the thread receives a WAIT response from step  46  or a PROCEED response from step  54  (due to a recoverable error), it can resume the system resource access by directly calling the callback function at a callback function call step  64 . Direct callback function call step  64  differs from service call  30  in that the wrapper function is not called. The top element on the stack contains all the information needed by the callback function to resume the system access. The callback function continues at stack pop step  36 .  
         [0050]    Although the preferred embodiment described above relates specifically to a system copy service and a particular callback function associated with that service, the principles of the present invention may similarly be applied to provision of system services of other types, such as disk input/output, data communication protocols, graphic window systems and interlock access to shared resources in multi-CPU systems. Furthermore, while the exemplary code in the Appendix below is written in the C language, it will be appreciated that the invention does not depend on features inherent in the C programming language and could be exploited in other computer programming languages.  
         [0051]    It will thus be appreciated that the preferred embodiments described above are cited by way of example, and that the present invention is not limited to what has been particularly shown and described hereinabove. Rather, the scope of the present invention includes both combinations and subcombinations of the various features described hereinabove, as well as variations and modifications thereof which would occur to persons skilled in the art upon reading the foregoing description and which are not disclosed in the prior art.