Erlang 21

driver_entry




erlang

driver_entry

C लाइब्रेरी

driver_entry

लाइब्रेरी सारांश

Erlang ड्राइवरों द्वारा प्रयुक्त ड्राइवर-प्रवेश संरचना।

विवरण

चेतावनी

चरम देखभाल के साथ इस कार्यक्षमता का उपयोग करें।

एक चालक कॉलबैक को वीएम के मूल कोड के प्रत्यक्ष विस्तार के रूप में निष्पादित किया जाता है। निष्पादन सुरक्षित वातावरण में नहीं किया जाता है। पूर्व-खाली शेड्यूलिंग या मेमोरी प्रोटेक्शन जैसे Erlang कोड को निष्पादित करते समय VM वही सेवाएं प्रदान नहीं कर सकता है जो प्रदान करता है। यदि ड्राइवर कॉलबैक फ़ंक्शन अच्छा व्यवहार नहीं करता है, तो पूरा वीएम दुर्व्यवहार करेगा।

  • एक ड्राइवर कॉलबैक जो क्रैश पूरे वीएम को क्रैश कर देगा।

  • गलत तरीके से लागू किया गया ड्राइवर कॉलबैक, वीएम आंतरिक स्थिति असंगतता का कारण बन सकता है, जो चालक कॉलबैक के बाद कॉल के बाद किसी भी समय वीएम की दुर्घटना, या वीएम के विविध दुर्व्यवहार का कारण बन सकता है।

  • वीएम की जवाबदेही को कम करने से पहले एक ड्राइवर कॉलबैक lengthy work करता है, और विविध अजीब व्यवहार का कारण बन सकता है। इस तरह के अजीब व्यवहार में शामिल हैं, लेकिन सीमित मेमोरी उपयोग और शेड्यूलर्स के बीच खराब लोड संतुलन तक सीमित नहीं हैं। अजीब व्यवहार जो लंबे समय तक काम करने के कारण हो सकता है, वह एरलांग / ओटीपी रिलीज के बीच भी भिन्न हो सकता है।

ERTS 5.9 (Erlang / OTP R15B) से ड्राइवर इंटरफेस को कॉलबैक output , control और call लिए बड़े प्रकार के साथ बदल दिया गया है। erl_driver में ड्राइवर version management देखें।

ध्यान दें

पुराने ड्राइवरों (5.9 से पहले एक ERTS संस्करण से एक erl_driver.h साथ संकलित) को अद्यतन किया जाना चाहिए और विस्तारित इंटरफ़ेस ( version management साथ) का उपयोग करना होगा।

driver_entry संरचना एक C संरचना है जिसे सभी Erlang ड्राइवर परिभाषित करते हैं। इसमें Erlang ड्राइवर के लिए प्रवेश बिंदु शामिल हैं, जो Erlang कोड द्वारा ड्राइवर तक पहुँचने पर Erlang एमुलेटर द्वारा कॉल किए जाते हैं।

erl_driver ड्राइवर API फ़ंक्शन को एक पोर्ट हैंडल की आवश्यकता होती है जो ड्राइवर आवृत्ति (और एमुलेटर में पोर्ट) की पहचान करता है। यह केवल start फ़ंक्शन के लिए पारित किया गया है, लेकिन अन्य कार्यों के लिए नहीं। start फ़ंक्शन एक ड्राइवर-परिभाषित हैंडल लौटाता है जो अन्य कार्यों के लिए पारित किया जाता है। एक सामान्य अभ्यास यह है कि start फंक्शन को कुछ एप्लिकेशन-डिफाइंड स्ट्रक्चर को आवंटित करें और इसमें port हैंडल को स्टैश करें, ताकि बाद में इसे ड्राइवर एपीआई फंक्शंस के साथ उपयोग किया जा सके।

ड्राइवर कॉलबैक फ़ंक्शंस को एरलैंग एमुलेटर से सिंक्रोनस कहा जाता है। यदि वे पूरा होने से पहले बहुत अधिक समय लेते हैं, तो वे एमुलेटर में समय पैदा कर सकते हैं। यदि आवश्यक हो, तो एम्यूलेटर उत्तरदायी होना चाहिए, कतार या अतुल्यकालिक कॉल का उपयोग करें।

ड्राइवर संरचना में ड्राइवर का नाम और कुछ 15 फ़ंक्शन बिंदु होते हैं, जिन्हें एमुलेटर द्वारा अलग-अलग समय पर बुलाया जाता है।

ड्राइवर से केवल निर्यात किया गया फ़ंक्शन driver_init । यह फ़ंक्शन driver_entry संरचना को driver_entry है जो ड्राइवर में अन्य कार्यों को इंगित करता है। driver_init फ़ंक्शन को मैक्रो, DRIVER_INIT(drivername) साथ घोषित किया गया है। (ऐसा इसलिए है क्योंकि अलग-अलग ऑपरेटिंग सिस्टम के लिए इसके अलग-अलग नाम हैं।)

C ++ में ड्राइवर लिखते समय, ड्राइवर प्रविष्टि "C" लिंकेज की होनी चाहिए। ऐसा करने का एक तरीका ड्राइवर प्रविष्टि से पहले निम्नलिखित पंक्ति को कहीं और रखना है:

extern "C" DRIVER_INIT(drivername);

जब चालक ने एमुलेटर पर driver_entry को पास किया है, तो ड्राइवर को driver_entry को संशोधित करने की अनुमति नहीं है

--enable-static-drivers माध्यम से स्थैतिक समावेशन के लिए ड्राइवर को संकलित करते --enable-static-drivers , आपको DRIVER_INIT घोषणा से पहले STATIC_ERLANG_DRIVER को परिभाषित करना होगा।

ध्यान दें

driver_entry const घोषित करें। ऐसा इसलिए है क्योंकि एमुलेटर को handle और handle handle2 फ़ील्ड को संशोधित करना होगा। एक सांख्यिकीय रूप से आवंटित, और कॉन्स्टेड- driver_entry किए गए driver_entry को केवल-पढ़ने के लिए मेमोरी में स्थित किया जा सकता है, जो एमुलेटर को क्रैश करने का कारण बनता है।

जानकारी का प्रकार

ErlDrvEntry

typedef struct erl_drv_entry {
    int (*init)(void);          /* Called at system startup for statically
                                   linked drivers, and after loading for
                                   dynamically loaded drivers */
#ifndef ERL_SYS_DRV
    ErlDrvData (*start)(ErlDrvPort port, char *command);
                                /* Called when open_port/2 is invoked,
                                   return value -1 means failure */
#else
    ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts);
                                /* Special options, only for system driver */
#endif
    void (*stop)(ErlDrvData drv_data);
                                /* Called when port is closed, and when the
                                   emulator is halted */
    void (*output)(ErlDrvData drv_data, char *buf, ErlDrvSizeT len);
                                /* Called when we have output from Erlang to
                                   the port */
    void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event); 
                                /* Called when we have input from one of
                                   the driver's handles */
    void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event);  
                                /* Called when output is possible to one of
                                   the driver's handles */
    char *driver_name;          /* Name supplied as command in
                                   erlang:open_port/2 */
    void (*finish)(void);       /* Called before unloading the driver -
                                   dynamic drivers only */
    void *handle;               /* Reserved, used by emulator internally */
    ErlDrvSSizeT (*control)(ErlDrvData drv_data, unsigned int command,
                            char *buf, ErlDrvSizeT len,
			    char **rbuf, ErlDrvSizeT rlen);
                                /* "ioctl" for drivers - invoked by
                                   port_control/3 */
    void (*timeout)(ErlDrvData drv_data);
                                /* Handling of time-out in driver */
    void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev);
                                /* Called when we have output from Erlang
                                   to the port */
    void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data);
    void (*flush)(ErlDrvData drv_data);
                                /* Called when the port is about to be
                                   closed, and there is data in the
                                   driver queue that must be flushed
                                   before 'stop' can be called */
    ErlDrvSSizeT (*call)(ErlDrvData drv_data, unsigned int command,
                         char *buf, ErlDrvSizeT len,
			 char **rbuf, ErlDrvSizeT rlen, unsigned int *flags);
                                /* Works mostly like 'control', a synchronous
                                   call into the driver */
    void* unused_event_callback;
    int extended_marker;        /* ERL_DRV_EXTENDED_MARKER */
    int major_version;          /* ERL_DRV_EXTENDED_MAJOR_VERSION */
    int minor_version;          /* ERL_DRV_EXTENDED_MINOR_VERSION */
    int driver_flags;           /* ERL_DRV_FLAGs */
    void *handle2;              /* Reserved, used by emulator internally */
    void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor);
                                /* Called when a process monitor fires */
    void (*stop_select)(ErlDrvEvent event, void* reserved);
                                /* Called to close an event object */
 } ErlDrvEntry;
int (*init)(void)

erl_ddll:load_driver/2 द्वारा लोड किए जाने के बाद सीधे कॉल किया गया erl_ddll:load_driver/2 (वास्तव में जब ड्राइवर को ड्राइवर सूची में जोड़ा जाता है)। ड्राइवर को 0 पर लौटना है, या, अगर ड्राइवर इनिशियलाइज़ नहीं कर सकता है, -1

ErlDrvData (*start)(ErlDrvPort port, char* command)

ड्राइवर के erlang:open_port/2 कॉल किया जाता है, जब erlang:open_port/2 कहा जाता है। ड्राइवर को नंबर> = 0 या एक पॉइंटर वापस करना है, या, यदि ड्राइवर को शुरू नहीं किया जा सकता है, तो तीन त्रुटि कोडों में से एक:

ERL_DRV_ERROR_GENERAL
सामान्य त्रुटि, कोई त्रुटि कोड नहीं
ERL_DRV_ERROR_ERRNO
ग़लती से त्रुटि कोड में त्रुटि
ERL_DRV_ERROR_BADARG
त्रुटि, badarg

यदि कोई त्रुटि कोड दिया गया है, तो पोर्ट प्रारंभ नहीं हुआ है।

void (*stop)(ErlDrvData drv_data)

पोर्ट बंद होने पर कॉल किया जाता है, erlang:port_close/1 साथ erlang:port_close/1 या Port ! {self(), close} Port ! {self(), close} । ध्यान दें कि पोर्ट स्वामी प्रक्रिया को समाप्त करने से भी पोर्ट बंद हो जाता है। यदि drv_data start में आवंटित मेमोरी के लिए एक पॉइंटर है, तो stop उस मेमोरी से drv_data का स्थान है।

void (*output)(ErlDrvData drv_data, char *buf, ErlDrvSizeT len)

एक Erlang प्रक्रिया ने पोर्ट पर डेटा भेजा है जब कॉल किया गया। डेटा को buf द्वारा इंगित किया गया है, और len बाइट्स है। डेटा पोर्ट के साथ Port ! {self(), {command, Data}} भेजा जाता है Port ! {self(), {command, Data}} Port ! {self(), {command, Data}} या erlang:port_command/2 साथ erlang:port_command/2 । पोर्ट को कैसे खोला गया था, इसके आधार पर, यह पूर्णांक 0...255 या एक बाइनरी की सूची होना चाहिए। erlang:open_port/2 देखें erlang:open_port/2 और erlang:port_command/2

void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event)
void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event)

ड्राइवर इवेंट (पैरामीटर event में निर्दिष्ट) को सिग्नल किए जाने पर कॉल किया जाता है। इसका उपयोग अतुल्यकालिक ड्राइवरों को "जागने" में मदद करने के लिए किया जाता है जब कुछ होता है।

यूनिक्स पर event एक पाइप या सॉकेट हैंडल (या कुछ ऐसा है जिसे select प्रणाली कॉल समझती है)।

विंडोज पर event एक Event या Semaphore (या ऐसा कुछ है जो WaitForMultipleObjects API फ़ंक्शन समझता है)। (एमुलेटर में कुछ प्रवंचना 64 Events की अंतर्निहित सीमा से अधिक उपयोग करने की अनुमति देती है।)

धागे और अतुल्यकालिक दिनचर्या के साथ इसका उपयोग करने के लिए, यूनिक्स पर एक पाइप और विंडोज पर एक Event बनाएं। जब दिनचर्या पूरी हो जाती है, तो पाइप को लिखें (विंडोज पर ready_input उपयोग करें), यह एमुलेटर कॉल के लिए तैयार करता ready_input या ready_output

गलत घटनाएं घट सकती हैं। वह है, ready_input या ready_output लिए कॉल हालांकि कोई वास्तविक घटनाओं का संकेत नहीं है। वास्तव में, यह दुर्लभ (और ओएस-निर्भर) है, लेकिन एक मजबूत चालक को इस तरह के मामलों को संभालने में सक्षम होना चाहिए।

char *driver_name

ड्राइवर का नाम। यह erlang:open_port/2 में उपयोग किए गए परमाणु के अनुरूप होना चाहिए erlang:open_port/2 , और ड्राइवर लाइब्रेरी फ़ाइल का नाम (विस्तार के बिना)।

void (*finish)(void)

ड्राइवर को उतारने पर erl_ddll ड्राइवर द्वारा कॉल किया जाता है। (इसे केवल डायनेमिक ड्राइवर्स में कहा जाता है।)

ड्राइवर को केवल erl_ddll:unload_driver/1 , या जब एमुलेटर erl_ddll:unload_driver/1 , तब कॉल करने के परिणामस्वरूप उतार दिया जाता है।

void *handle

यह क्षेत्र एमुलेटर के आंतरिक उपयोग के लिए आरक्षित है। एमुलेटर इस क्षेत्र को संशोधित करेगा, इसलिए यह महत्वपूर्ण है कि driver_entry को const घोषित नहीं किया गया है।

ErlDrvSSizeT (*control)(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen)

erlang:port_control/3 साथ आहूत एक विशेष दिनचर्या erlang:port_control/3 । यह Erlang ड्राइवरों के लिए "ioctl" की तरह थोड़ा काम करता है। port_control/3 निर्दिष्ट डेटा buf और len में आता है। ड्राइवर *rbuf और rlen का उपयोग करके डेटा वापस भेज सकता है।

यह ड्राइवर को कॉल करने और प्रतिक्रिया प्राप्त करने का सबसे तेज़ तरीका है। यह एर्लैंग एमुलेटर में कोई संदर्भ स्विच नहीं करता है और इसके लिए कोई संदेश पास करने की आवश्यकता नहीं है। यह तेजी से निष्पादन प्राप्त करने के लिए सी फ़ंक्शन को कॉल करने के लिए उपयुक्त है, जब एर्लैंग बहुत धीमा है।

यदि ड्राइवर डेटा वापस करना चाहता है, तो इसे rbuf में वापस करना है। जब control को कहा जाता है, तो *rbuf एक rlen बाइट के डिफ़ॉल्ट बफ़र को rlen , जिसका उपयोग डेटा वापस करने के लिए किया जा सकता है। पोर्ट कंट्रोल फ्लैग (जो erl_driver:set_port_control_flags साथ सेट erl_driver:set_port_control_flags ) के आधार पर डेटा अलग-अलग लौटाया जाता है।

यदि ध्वज PORT_CONTROL_FLAG_BINARY सेट है, तो एक बाइनरी वापस आ जाती है। छोटे बायनेरिज़ को डिफ़ॉल्ट बफ़र में कच्चे डेटा लिखकर लौटाया जा सकता है। एक बाइनरी को *rbuf साथ आवंटित बाइनरी को इंगित करने के लिए *rbuf सेट करके भी लौटाया जा सकता है erl_driver:driver_alloc_binary control वापस आने के बाद यह बाइनरी स्वत: मुक्त हो जाती है। ड्राइवर केवल erl_driver:driver_binary_inc_refc साथ पढ़ने के लिए बाइनरी को बनाए रख सकता है erl_driver:driver_binary_inc_refc को erl_driver:driver_free_binary साथ बाद में मुक्त किया जा सकता है erl_driver:driver_free_binary control वापस आने के बाद बाइनरी को बदलने की अनुमति नहीं है। यदि *rbuf को NULL सेट किया जाता NULL , तो एक खाली सूची वापस आ जाती है।

यदि ध्वज 0 सेट है, तो डेटा को पूर्णांकों की सूची के रूप में लौटाया जाता है। या तो डिफ़ॉल्ट बफर का उपयोग करें या *rbuf साथ आवंटित बड़े बफर को इंगित करने के लिए *rbuf सेट करें erl_driver:driver_alloc control वापस आने के बाद बफर स्वचालित रूप से मुक्त हो जाता है।

यदि कुछ बाइट्स से अधिक लौटाया जाता है, तो बायनेरी का उपयोग तेज होता है।

वापसी मूल्य *rbuf में *rbuf गए बाइट्स की संख्या है।

void (*timeout)(ErlDrvData drv_data)

ड्राइवर के टाइमर 0 तक पहुंचने के बाद किसी भी समय कॉल किया जाता है। टाइमर erl_driver:driver_set_timer साथ सक्रिय है। ड्राइवरों के बीच कोई प्राथमिकता या आदेश मौजूद नहीं है, इसलिए यदि कई ड्राइवर एक ही समय में बाहर जाते हैं, तो उनमें से किसी को भी पहले बुलाया जाता है।

void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev)

जब भी पोर्ट को लिखा जाता है तो कॉल किया जाता है। यदि यह NULL , तो output फ़ंक्शन को इसके बजाय कहा जाता है। यह फ़ंक्शन output तुलना में तेज़ है, क्योंकि यह सीधे एक ErlIOVec लेता है, जिसके लिए डेटा की प्रतिलिपि की आवश्यकता नहीं होती है। पोर्ट बाइनरी मोड में होना है, erlang:open_port/2 देखें erlang:open_port/2

ErlIOVec में SysIOVec , writev और एक या अधिक बायनेरिज़ दोनों उपयुक्त हैं। यदि ड्राइवर से लौटने पर ये बायनेरिज़ बनाए outputv , तो उन्हें कतारबद्ध किया जा सकता है (उदाहरण के लिए, erl_driver:driver_enq_bin ) का उपयोग करके या, यदि उन्हें स्थिर या वैश्विक चर में रखा जाता है, तो संदर्भ काउंटर को erl_driver:driver_enq_bin जा सकता है।

void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data)

एक एसिंक्रोनस कॉल पूरा होने के बाद कॉल किया गया। एसिंक्रोनस कॉल को erl_driver:driver_async साथ शुरू किया erl_driver:driver_async । इस फ़ंक्शन को एसलैंगस फ़ंक्शन के विपरीत Erlang emulator थ्रेड से कहा जाता है, जिसे कुछ थ्रेड में कहा जाता है (यदि मल्टी-थ्रेडिंग सक्षम है)।

void (*flush)(ErlDrvData drv_data)

पोर्ट बंद होने के बारे में कहा जाता है और ड्राइवर कतार में डेटा होता है जिसे 'स्टॉप' से पहले फ्लश किया जाना चाहिए।

ErlDrvSSizeT (*call)(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen, unsigned int *flags)

erlang:port_call/3 से erlang:port_call/3 यह control कॉलबैक की तरह बहुत काम करता है, लेकिन इनपुट और आउटपुट के लिए बाहरी शब्द प्रारूप का उपयोग करता है।

command एक पूर्णांक है, जो erlang:port_call/3 से कॉल से प्राप्त होता है ( erlang:port_call/3 का दूसरा तर्क erlang:port_call/3 )।

buf और len कॉल को तर्क प्रदान करते हैं (तीसरा तर्क erlang:port_call/3 )। उन्हें ei कार्यों का उपयोग करके डिकोड किया जा सकता है।

rbuf एक रिटर्न बफर की ओर rlen , rlen बाइट्स लंबा। वापसी डेटा बाहरी (बाइनरी) प्रारूप में एक वैध एर्लैंग शब्द होना है। यह एक Erlang शब्द में परिवर्तित होता है और erlang:port_call/3 से कॉलर को लौटाया जाता है। यदि डेटा वापस करने के लिए rlen बाइट्स से अधिक स्थान आवश्यक है, तो *rbuf को erl_driver:driver_alloc साथ आवंटित मेमोरी में सेट किया जा सकता है। call वापस आने के बाद यह मेमोरी अपने आप फ़्री हो जाती है।

वापसी मूल्य *rbuf में *rbuf गए बाइट्स की संख्या है। यदि ERL_DRV_ERROR_GENERAL लौटाया जाता है (या वास्तव में, कुछ भी <0), erlang:port_call/3 एक BAD_ARG फेंकता है।

void (*event)(ErlDrvData drv_data, ErlDrvEvent event, ErlDrvEventData event_data)

जानबूझकर अनिर्दिष्ट छोड़ दिया।

int extended_marker

यह फ़ील्ड या तो ERL_DRV_EXTENDED_MARKER बराबर है या 0 । एक पुराना ड्राइवर (विस्तारित ड्राइवर इंटरफ़ेस के बारे में नहीं जानता) इस क्षेत्र को 0 पर सेट करना है। यदि यह फ़ील्ड 0 , तो निम्न सभी फ़ील्ड भी 0 या NULL होना चाहिए यदि यह एक पॉइंटर फ़ील्ड है।

int major_version

यदि फ़ील्ड ERL_DRV_EXTENDED_MAJOR_VERSION बराबर है, तो यह फ़ील्ड ERL_DRV_EXTENDED_MAJOR_VERSION बराबर है।

int minor_version

यदि फ़ील्ड extended_marker ERL_DRV_EXTENDED_MARKER बराबर है, तो यह फ़ील्ड ERL_DRV_EXTENDED_MINOR_VERSION बराबर है।

int driver_flags

इस क्षेत्र का उपयोग चालक क्षमता और अन्य सूचना को रनटाइम सिस्टम में पारित करने के लिए किया जाता है। यदि फ़ील्ड extended_marker ERL_DRV_EXTENDED_MARKER बराबर है, तो इसमें 0 या ड्राइवर फ़्लैग ( ERL_DRV_FLAG_* ) OR'ed बिटवाइज़ सम्‍मिलित है। निम्नलिखित ड्राइवर झंडे मौजूद हैं:

ERL_DRV_FLAG_USE_PORT_LOCKING

रनटाइम सिस्टम सभी स्तरों पर पोर्ट-लेवल लॉकिंग का उपयोग करता है, जब ड्राइवर SMP सपोर्ट के साथ रनटाइम सिस्टम में चलाया जाता है, तो ड्राइवर-लेवल लॉकिंग के बजाय इस ड्राइवर को निष्पादित करता है। अधिक जानकारी के लिए, erl_driver देखें।

ERL_DRV_FLAG_SOFT_BUSY

ऐसे चिह्न जो ड्राइवर इंस्टेंस को output और / या outputv कॉलबैक में कॉल किए जा सकते हैं, हालांकि ड्राइवर के उदाहरण ने खुद को व्यस्त के रूप में चिह्नित किया है (देखें erl_driver:set_busy_port )। ERTS 5.7.4 से इस ध्वज को Erlang वितरण द्वारा उपयोग किए जाने वाले ड्राइवरों के लिए आवश्यक है (व्यवहार हमेशा वितरण द्वारा उपयोग किए गए ड्राइवरों द्वारा आवश्यक होता है)।

ERL_DRV_FLAG_NO_BUSY_MSGQ

व्यस्त पोर्ट संदेश कतार कार्यक्षमता अक्षम करता है। अधिक जानकारी के लिए, erl_driver:erl_drv_busy_msgq_limits देखें।

ERL_DRV_FLAG_USE_INIT_ACK

जब यह ध्वज निर्दिष्ट किया जाता है, तो लिंक्ड-इन ड्राइवर को मैन्युअल रूप से स्वीकार करना होगा कि पोर्ट को सफलतापूर्वक erl_driver:erl_drv_init_ack() का उपयोग करके शुरू किया गया है। यह कार्यान्वयनकर्ता को erlang:open_port बनाने की अनुमति देता है erlang:open_port कुछ प्रारंभिक एसिंक्रोनस आरंभीकरण के बाद badarg साथ badarg बाहर निकलना।

void *handle2

यह क्षेत्र एमुलेटर के आंतरिक उपयोग के लिए आरक्षित है। एमुलेटर इस क्षेत्र को संशोधित करता है, इसलिए यह महत्वपूर्ण है कि driver_entry को const घोषित नहीं किया गया है।

void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor)

एक निगरानी प्रक्रिया से बाहर निकलने पर कॉल किया जाता है। drv_data पोर्ट से जुड़ा डेटा है जिसके लिए प्रक्रिया की निगरानी की जाती है ( erl_driver:driver_monitor_process का उपयोग erl_driver:driver_monitor_process ) और monitor बनाते समय ErlDrvMonitor संरचना से भरा होता है। ड्राइवर इंटरफ़ेस फ़ंक्शन erl_driver:driver_get_monitored_process का उपयोग एक ErlDrvTermData रूप में बाहर निकलने की प्रक्रिया की ID प्राप्त करने के लिए किया जा सकता है।

void (*stop_select)(ErlDrvEvent event, void* reserved)

erl_driver:driver_select ओर से erl_driver:driver_select जब किसी इवेंट ऑब्जेक्ट को बंद करना सुरक्षित हो।

यूनिक्स पर एक विशिष्ट कार्यान्वयन close((int)event)

reserved तर्क भविष्य के उपयोग के लिए अभिप्रेत है और इसे अनदेखा किया जाना है।

अधिकांश कॉलबैक फ़ंक्शन के विपरीत, stop_select को किसी भी पोर्ट से स्वतंत्र कहा जाता है। फ़ंक्शन के लिए कोई ErlDrvData तर्क पारित नहीं किया गया है। कोई ड्राइवर लॉक या पोर्ट लॉक आयोजित करने की गारंटी नहीं है। जिस driver_select को driver_select कहा जाता है उसे driver_select के समय भी बंद किया जा सकता है। लेकिन यह भी मामला हो सकता है कि stop_select को सीधे erl_driver:driver_select कहा जाता है।

यह erl_driver में किसी भी फ़ंक्शन को stop_select से कॉल करने की अनुमति नहीं है। यह सख्त सीमा है क्योंकि अस्थिर संदर्भ जो stop_select कहा जा सकता है।

यह भी देखें

erl_driver , erlang(3) , erl_ddll(3)