Michal Privoznik писал 2013-10-14 11:39:> On 14.10.2013 10:33, Alexandr wrote: >> Michal Privoznik писал 2013-10-14 08:48: >>> On 14.10.2013 02:42, Alexandr wrote: >>>> good day to all. >>>> i still have not solved my problem with event handling. >>>> currently i have following code >>>> >>>> >>>> void libvirt_eventloop_thr_func() >>>> { >>>> while(true) //TODO: stop somehow on exit >>>> { >>>> if(virEventRunDefaultImpl() < 0) >>>> { >>>> virErrorPtr err = virGetLastError(); >>>> fprintf(stderr, "Failed to run event loop: %s\n", err && >>>> err->message ? err->message : "Unknown error"); >>>> } >>>> } >>>> } >>>> >>>> >>>> >>>> ... >>>> >>>> virSetErrorFunc(NULL, libvirt_error_handler); >>>> libvirt_connection = virConnectOpen("qemu:///system"); >>> >>> Move this line ^^^ ... >>> >>>> if (virEventRegisterDefaultImpl() < 0) >>>> { >>>> virErrorPtr err = virGetLastError(); >>>> fprintf(stderr, "Failed to register event implementation: >>>> %s\n", >>>> err && err->message ? err->message: "Unknown error"); >>>> return -1; >>>> } >>>> { >>>> int callback >>>> virConnectDomainEventRegisterAny(libvirt_connection, NULL, >>>> VIR_DOMAIN_EVENT_ID_LIFECYCLE, >>>> VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); >>>> if(callback == -1) >>>> { >>>> std::cout<<"Error: failed to register domain event >>>> handle >>>> callback\n"; >>>> return -1; >>>> } >>>> } >>>> >>>> boost::thread(boost::bind(&libvirt_eventloop_thr_func)); >>> >>> ... over here. The virConnectOpen detects if there's an even loop >>> registered. And in your case you don't have any registered when >>> calling it. >>> >>> Michal >> >> thank you very match, it now working as expected, but one thing are >> missed from documentations, current api docs says what i do not need >> to >> call virInitialize(), but if i call virEventRegisterDefaultImpl() >> without calling virInitialize() programm crashing (i have not used >> virInitialize() in my programm, just virConnectOpen() as docs said). >> problem solved now. > > From virInitialize documentation [1]: > > "The only time it would be necessary to call virInitialize is if the > application did not invoke virConnectOpen as its first API call." > > Which is your case. But if you believe this can be written better, > propose a patch and I'll review it. > > Michal > > 1: http://libvirt.org/html/libvirt-libvirt.html#virInitializeyes, i read this, but my first api call is virSetErrorFunc(), and this api call working fine without virInitialize(), this create a little confusion. i think i can't help with documentation, english is not my native language and it is hard to me to write on it, and mostly impossible to write correctly.
On 14.10.2013 10:57, Alexandr wrote:> Michal Privoznik писал 2013-10-14 11:39: >> On 14.10.2013 10:33, Alexandr wrote: >>> Michal Privoznik писал 2013-10-14 08:48: >>>> On 14.10.2013 02:42, Alexandr wrote: >>>>> good day to all. >>>>> i still have not solved my problem with event handling. >>>>> currently i have following code >>>>> >>>>> >>>>> void libvirt_eventloop_thr_func() >>>>> { >>>>> while(true) //TODO: stop somehow on exit >>>>> { >>>>> if(virEventRunDefaultImpl() < 0) >>>>> { >>>>> virErrorPtr err = virGetLastError(); >>>>> fprintf(stderr, "Failed to run event loop: %s\n", err && >>>>> err->message ? err->message : "Unknown error"); >>>>> } >>>>> } >>>>> } >>>>> >>>>> >>>>> >>>>> ... >>>>> >>>>> virSetErrorFunc(NULL, libvirt_error_handler); >>>>> libvirt_connection = virConnectOpen("qemu:///system"); >>>> >>>> Move this line ^^^ ... >>>> >>>>> if (virEventRegisterDefaultImpl() < 0) >>>>> { >>>>> virErrorPtr err = virGetLastError(); >>>>> fprintf(stderr, "Failed to register event implementation: >>>>> %s\n", >>>>> err && err->message ? err->message: "Unknown error"); >>>>> return -1; >>>>> } >>>>> { >>>>> int callback >>>>> virConnectDomainEventRegisterAny(libvirt_connection, NULL, >>>>> VIR_DOMAIN_EVENT_ID_LIFECYCLE, >>>>> VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); >>>>> if(callback == -1) >>>>> { >>>>> std::cout<<"Error: failed to register domain event handle >>>>> callback\n"; >>>>> return -1; >>>>> } >>>>> } >>>>> >>>>> boost::thread(boost::bind(&libvirt_eventloop_thr_func)); >>>> >>>> ... over here. The virConnectOpen detects if there's an even loop >>>> registered. And in your case you don't have any registered when >>>> calling it. >>>> >>>> Michal >>> >>> thank you very match, it now working as expected, but one thing are >>> missed from documentations, current api docs says what i do not need to >>> call virInitialize(), but if i call virEventRegisterDefaultImpl() >>> without calling virInitialize() programm crashing (i have not used >>> virInitialize() in my programm, just virConnectOpen() as docs said). >>> problem solved now. >> >> From virInitialize documentation [1]: >> >> "The only time it would be necessary to call virInitialize is if the >> application did not invoke virConnectOpen as its first API call." >> >> Which is your case. But if you believe this can be written better, >> propose a patch and I'll review it. >> >> Michal >> >> 1: http://libvirt.org/html/libvirt-libvirt.html#virInitialize > > yes, i read this, but my first api call is virSetErrorFunc(), and this > api call working fine without virInitialize(), this create a little > confusion.The fact that some functions *seem* to work well even without virInitialize() called doesn't mean that you shouldn't call it. When I started to write some programs involving libvirt I've looked into virsh.c a lot and basically copied the main structure. virsh is guaranteed to work and use the correct sequence of APIs. The other option is to look at examples, e.g. event-test [2]. Michal 2: http://libvirt.org/git/?p=libvirt.git;a=blob;f=examples/domain-events/events-c/event-test.c;h=52aa3d08d7326e422c12a8521717c3d55b2d8afd;hb=HEAD#l458
Michal Privoznik писал 2013-10-14 12:04:> On 14.10.2013 10:57, Alexandr wrote: >> Michal Privoznik писал 2013-10-14 11:39: >>> On 14.10.2013 10:33, Alexandr wrote: >>>> Michal Privoznik писал 2013-10-14 08:48: >>>>> On 14.10.2013 02:42, Alexandr wrote: >>>>>> good day to all. >>>>>> i still have not solved my problem with event handling. >>>>>> currently i have following code >>>>>> >>>>>> >>>>>> void libvirt_eventloop_thr_func() >>>>>> { >>>>>> while(true) //TODO: stop somehow on exit >>>>>> { >>>>>> if(virEventRunDefaultImpl() < 0) >>>>>> { >>>>>> virErrorPtr err = virGetLastError(); >>>>>> fprintf(stderr, "Failed to run event loop: %s\n", err >>>>>> && >>>>>> err->message ? err->message : "Unknown error"); >>>>>> } >>>>>> } >>>>>> } >>>>>> >>>>>> >>>>>> >>>>>> ... >>>>>> >>>>>> virSetErrorFunc(NULL, libvirt_error_handler); >>>>>> libvirt_connection = virConnectOpen("qemu:///system"); >>>>> >>>>> Move this line ^^^ ... >>>>> >>>>>> if (virEventRegisterDefaultImpl() < 0) >>>>>> { >>>>>> virErrorPtr err = virGetLastError(); >>>>>> fprintf(stderr, "Failed to register event implementation: >>>>>> %s\n", >>>>>> err && err->message ? err->message: "Unknown error"); >>>>>> return -1; >>>>>> } >>>>>> { >>>>>> int callback >>>>>> virConnectDomainEventRegisterAny(libvirt_connection, NULL, >>>>>> VIR_DOMAIN_EVENT_ID_LIFECYCLE, >>>>>> VIR_DOMAIN_EVENT_CALLBACK(domain_event_handler), NULL, NULL); >>>>>> if(callback == -1) >>>>>> { >>>>>> std::cout<<"Error: failed to register domain event >>>>>> handle >>>>>> callback\n"; >>>>>> return -1; >>>>>> } >>>>>> } >>>>>> >>>>>> boost::thread(boost::bind(&libvirt_eventloop_thr_func)); >>>>> >>>>> ... over here. The virConnectOpen detects if there's an even loop >>>>> registered. And in your case you don't have any registered when >>>>> calling it. >>>>> >>>>> Michal >>>> >>>> thank you very match, it now working as expected, but one thing are >>>> missed from documentations, current api docs says what i do not need >>>> to >>>> call virInitialize(), but if i call virEventRegisterDefaultImpl() >>>> without calling virInitialize() programm crashing (i have not used >>>> virInitialize() in my programm, just virConnectOpen() as docs said). >>>> problem solved now. >>> >>> From virInitialize documentation [1]: >>> >>> "The only time it would be necessary to call virInitialize is if the >>> application did not invoke virConnectOpen as its first API call." >>> >>> Which is your case. But if you believe this can be written better, >>> propose a patch and I'll review it. >>> >>> Michal >>> >>> 1: http://libvirt.org/html/libvirt-libvirt.html#virInitialize >> >> yes, i read this, but my first api call is virSetErrorFunc(), and this >> api call working fine without virInitialize(), this create a little >> confusion. > > The fact that some functions *seem* to work well even without > virInitialize() called doesn't mean that you shouldn't call it. When I > started to write some programs involving libvirt I've looked into > virsh.c a lot and basically copied the main structure. virsh is > guaranteed to work and use the correct sequence of APIs. The other > option is to look at examples, e.g. event-test [2]. > > Michal > > 2: > http://libvirt.org/git/?p=libvirt.git;a=blob;f=examples/domain-events/events-c/event-test.c;h=52aa3d08d7326e422c12a8521717c3d55b2d8afd;hb=HEAD#l458maybe write something like "virInitialize() must be first api call except situations when first call is virConnectOpen()" ?