Appendix B Open Server Migration To Jaguar


Additional event handler information

This section contains additional information relevant to coding event handlers.

Calling convention for event handlers

All event handlers, error handlers, and any other function that is installed as a callback in the Jaguar server runtime must be coded according to the following rules:

Initialization, run, start and exit events

An application's initialization handler and start handler are invoked when the server starts up. The exit handler is invoked when the server shuts down. Initialization and exit handlers are typically used to manage global resources used by the application. The sequence is as follows:

  1. Server initialization - Initialization handler (if installed) is called.
  2. Server start-up - Initialization handler has returned. The Start handler is called. The server is now ready to spawn new threads, but will not accept client connections until after the Start handler returns. The Start handler can spawn service (non-client) threads if necessary.
  3. Normal operation - The server accepts client connections and associates each with a thread, spawning new threads when necessary. Each time a client connects, the server calls the application's connect handler. Each time a client disconnects, the server calls the application's disconnect handler.
  4. Server shutdown - The server terminates all threads, then calls the exit handler.

Start handler template

The template for a start handler is:

#include <ospublic.h>

CS_RETCODE CS_PUBLIC start_handler (
CS_CONTEXT *ctx
)

where

context - is pointer to the CS_CONTEXT structure.

Start handlers must return CS_SUCCEED unless an error occurs that prevents the application from running successfully. Returning a value other than CS_SUCCEED aborts the server start-up sequence.

Your application does not require a start handler unless you want to use service threads or create global mutexes. In this case, the service threads must be created in the start handler.

Exit handler template

The template for an exit handler is:

#include <ospublic.h>

CS_RETCODE CS_PUBLIC exit_handler(
CS_CONTEXT *context
)
{
... your code goes here ...
return CS_SUCCEED;
}

where

context - is pointer to the CS_CONTEXT structure.

Exit handlers must return CS_SUCCEED.

Connect and disconnect handlers

Connect and disconnect handlers are invoked when client applications open and close connections to the Jaguar server.

The connect and disconnect handler examples in this chapter call Server-Library routines. You can use these routines to perform user authentication.

Note   You can also use roles to perform user authentication. See the Jaguar CTS System Administration Guide for more information.

You can find documentation for these routines in the Open Server Server-Library/C Reference Manual. The latest version of this book is available with the 11.1 Open Server™ product. You can also view it on the web from the Technical Library page:

http://sybooks.sybase.com

Connect handler

The connect handler can be used to authenticate the connection's user name. Users must be validated based on user name/password, and you must supply code for password maintenance and checking.

Note   srv_thread_props(SRV_T_USERDATA) is off-limits to Jaguar event programmers.

The following is an example of a connect handler that logs the user name, password, and locale name when a connection is opened:

CS_RETCODE CS_PUBLIC
debug_connect(srvproc)
SRV_PROC *srvproc;
{
CS_INT spid;
CS_INT ulen;
CS_INT plen;
CS_INT llen;
CS_CHAR msg[CS_MAX_MSG];
CS_CHAR user[CS_MAX_NAME+1];
CS_CHAR password[CS_MAX_NAME+1];
    /* Initialization                           */
spid = 0;
    /* Get the spid    */
if (srv_thread_props(srvproc, CS_GET, SRV_T_SPID,
(CS_VOID *)&spid,
CS_SIZEOF(spid), NIL(CS_INT *)) != CS_SUCCEED)
{
return (CS_FAIL);
}
    /*
** Get the username and password
*/
if (srv_thread_props(srvproc, CS_GET, SRV_T_USER,
(CS_VOID *)user,
CS_MAX_NAME, &ulen) != CS_SUCCEED)
{
return (CS_FAIL);
}
    if (srv_thread_props(srvproc, CS_GET, SRV_T_PWD, 
(CS_VOID *)password,
CS_MAX_NAME, &plen) != CS_SUCCEED)
{
return (CS_FAIL);
}
    /* Null terminate the username and password      */
user[ulen] = (CS_CHAR)'\0';
password[plen] = (CS_CHAR)'\0';
    /* Log the username and password values.    */
sprintf(msg,"SPID %d) user '%s', password '%s'\n",
spid, user, password);
SRV_LOG(CS_TRUE, msg, CS_NULLTERM);
    return (CS_SUCCEED);
}

Disconnect handler

The following is an example of a disconnect handler:

CS_RETCODE CS_PUBLIC
fullpass_disconnect(srvproc)
SRV_PROC *srvproc;
{
    CS_INT      spid;
CS_CHAR msg[CS_MAX_MSG];
    /* Initialization                           */
spid = 0;
    /* Get the spid    */
if (srv_thread_props(srvproc, CS_GET, SRV_T_SPID,
(CS_VOID *)&spid,
CS_SIZEOF(spid), NIL(CS_INT *)) != CS_SUCCEED)
{
return (CS_FAIL);
}
    sprintf(msg,"SPID %d disconnected.\n", spid);
SRV_LOG(CS_TRUE, msg, CS_NULLTERM);
    return CS_SUCCEED;
}

Build with the Visual C++ IDE

If you use the Visual C++ IDE or another command line compiler to build your DLL, make sure that you specify the correct options so that the compiler generates C functions using the standard C calling convention.

After you build the DLL, copy it to the directory specified as the library directory for your server in the Jaguar Manager (field "Library Directory:"). See the Jaguar CTS System Administration Guide for instructions on using Jaguar Manager.

A sample module definition (.def) file

The Jaguar Manager will generate a .def file for your component. Visual C++ requires a module definition file that specifies which functions are exported from a DLL and some options that control how the DLL is loaded into memory. Module definition files end with the extension .def.

For most projects, you can use the generated file as-is. In some cases, you may want to edit settings other than those in the EXPORTS section. For example, your component may perform better with a smaller or larger HEAPSIZE setting.

Note   Never edit the generated function names in the EXPORTS section of the .def file for a C component, otherwise, the Jaguar dispatcher will not be able to call your methods.

Below is the example module definition file for the sample Enrollment component:

LIBRARY libEnrollment     INITINSTANCE
Description 'EnrollmentComponent - Jaguar Server'
HEAPSIZE 22000
PROTMODE
CODE LOADONCALL EXECUTEREAD NONCONFORMING
DATA PRELOAD READWRITE MULTIPLE NONSHARED
EXPORTS
__skl_Enrollment_v_1_0_getMajorList
__skl_Enrollment_v_1_0_getCourses
__skl_Enrollment_v_1_0_getStudentRecord
__skl_Enrollment_v_1_0_putCourseRecord
__skl_Enrollment_v_1_0_destroy
__skl_Enrollment_v_1_0_createStudentRecord
__skl_Enrollment_v_1_0_create
__skl_Enrollment_v_1_0_getMajorEnrollmentRecord
__skl_Enrollment_v_1_0_removeCourseRecord
__skl_Enrollment_v_1_0_getCourseList
__skl_Enrollment_v_1_0_getAllEnrollmentRecord

For components, the .def file must use the Jaguar-mangled function names as shown in the example. For each method in your component, the mangled name is:

__skl_Comp_v_1_0_method

where

Comp is the component name.

method is the method name.

 


Copyright © 2000 Sybase, Inc. All rights reserved.